(function (g, f) {
    if ("object" == typeof exports && "object" == typeof module) {
      module.exports = f();
    } else if ("function" == typeof define && define.amd) {
      define("agCharts", [], f);
    } else if ("object" == typeof exports) {
      exports["agCharts"] = f();
    } else {
      g["agCharts"] = f();
    }
  }(this, () => {
var exports = {};
var module = { exports };
if (typeof require === 'undefined') {
    function require(name) {
        
        throw new Error('Unknown module: ' + name);
    }
}
        
"use strict";
var __knownSymbol = (name, symbol) => {
  return (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
};
var __await = function(promise, isYieldStar) {
  this[0] = promise;
  this[1] = isYieldStar;
};
var __yieldStar = (value) => {
  var obj = value[__knownSymbol("asyncIterator")];
  var isAwait = false;
  var method;
  var it = {};
  if (obj == null) {
    obj = value[__knownSymbol("iterator")]();
    method = (k) => it[k] = (x) => obj[k](x);
  } else {
    obj = obj.call(value);
    method = (k) => it[k] = (v) => {
      if (isAwait) {
        isAwait = false;
        if (k === "throw")
          throw v;
        return v;
      }
      isAwait = true;
      return {
        done: false,
        value: new __await(new Promise((resolve) => {
          var x = obj[k](v);
          if (!(x instanceof Object))
            throw TypeError("Object expected");
          resolve(x);
        }), 1)
      };
    };
  }
  return it[__knownSymbol("iterator")] = () => it, method("next"), "throw" in obj ? method("throw") : it.throw = (x) => {
    throw x;
  }, "return" in obj && method("return"), it;
};

// packages/ag-charts-community/dist/package/main.cjs.js
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __reflectGet = Reflect.get;
var __knownSymbol2 = (name, symbol) => {
  return (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
};
var __pow = Math.pow;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
  var target = {};
  for (var prop in source)
    if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
      target[prop] = source[prop];
  if (source != null && __getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(source)) {
      if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
        target[prop] = source[prop];
    }
  return target;
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp(target, key, result);
  return result;
};
var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
var __await2 = function(promise, isYieldStar) {
  this[0] = promise;
  this[1] = isYieldStar;
};
var __yieldStar2 = (value) => {
  var obj = value[__knownSymbol2("asyncIterator")];
  var isAwait = false;
  var method;
  var it = {};
  if (obj == null) {
    obj = value[__knownSymbol2("iterator")]();
    method = (k) => it[k] = (x) => obj[k](x);
  } else {
    obj = obj.call(value);
    method = (k) => it[k] = (v) => {
      if (isAwait) {
        isAwait = false;
        if (k === "throw")
          throw v;
        return v;
      }
      isAwait = true;
      return {
        done: false,
        value: new __await2(new Promise((resolve) => {
          var x = obj[k](v);
          if (!(x instanceof Object))
            throw TypeError("Object expected");
          resolve(x);
        }), 1)
      };
    };
  }
  return it[__knownSymbol2("iterator")] = () => it, method("next"), "throw" in obj ? method("throw") : it.throw = (x) => {
    throw x;
  }, "return" in obj && method("return"), it;
};
var main_exports = {};
__export(main_exports, {
  AgChart: () => AgChart,
  AgCharts: () => AgCharts,
  AgErrorBarSupportedSeriesTypes: () => AgErrorBarSupportedSeriesTypes,
  Marker: () => Marker,
  VERSION: () => VERSION,
  _ModuleSupport: () => module_support_exports,
  _Scale: () => sparklines_scale_exports,
  _Scene: () => integrated_charts_scene_exports,
  _Theme: () => integrated_charts_theme_exports,
  _Util: () => sparklines_util_exports,
  __FORCE_MODULE_DETECTION: () => __FORCE_MODULE_DETECTION,
  time: () => time_exports
});
module.exports = __toCommonJS(main_exports);
var AgErrorBarSupportedSeriesTypes = ["bar", "line", "scatter"];
var __FORCE_MODULE_DETECTION = 0;
var time_exports = {};
__export(time_exports, {
  day: () => day,
  friday: () => friday,
  hour: () => hour,
  millisecond: () => millisecond,
  minute: () => minute,
  monday: () => monday,
  month: () => month,
  saturday: () => saturday,
  second: () => second,
  sunday: () => sunday,
  thursday: () => thursday,
  tuesday: () => tuesday,
  utcDay: () => utcDay,
  utcHour: () => utcHour,
  utcMinute: () => utcMinute,
  utcMonth: () => utcMonth,
  utcYear: () => utcYear,
  wednesday: () => wednesday,
  year: () => year
});
var TimeInterval = class {
  constructor(_encode, _decode, _rangeCallback) {
    this._encode = _encode;
    this._decode = _decode;
    this._rangeCallback = _rangeCallback;
  }
  /**
   * Returns a new date representing the latest interval boundary date before or equal to date.
   * For example, `day.floor(date)` typically returns 12:00 AM local time on the given date.
   * @param date
   */
  floor(date) {
    const d = new Date(date);
    const e = this._encode(d);
    return this._decode(e);
  }
  /**
   * Returns a new date representing the earliest interval boundary date after or equal to date.
   * @param date
   */
  ceil(date) {
    const d = new Date(Number(date) - 1);
    const e = this._encode(d);
    return this._decode(e + 1);
  }
  /**
   * Returns an array of dates representing every interval boundary after or equal to start (inclusive) and before stop (exclusive).
   * @param start Range start.
   * @param stop Range end.
   * @param extend If specified, the requested range will be extended to the closest "nice" values.
   */
  range(start, stop, extend) {
    var _a;
    const rangeCallback = (_a = this._rangeCallback) == null ? void 0 : _a.call(this, start, stop);
    const e0 = this._encode(extend ? this.floor(start) : this.ceil(start));
    const e1 = this._encode(extend ? this.ceil(stop) : this.floor(stop));
    if (e1 < e0) {
      return [];
    }
    const range3 = [];
    for (let e = e0; e <= e1; e++) {
      const d = this._decode(e);
      range3.push(d);
    }
    rangeCallback == null ? void 0 : rangeCallback();
    return range3;
  }
};
var CountableTimeInterval = class extends TimeInterval {
  getOffset(snapTo, step) {
    const s = typeof snapTo === "number" || snapTo instanceof Date ? this._encode(new Date(snapTo)) : 0;
    return Math.floor(s) % step;
  }
  /**
   * Returns a filtered view of this interval representing every step'th date.
   * It can be a number of minutes, hours, days etc.
   * Must be a positive integer.
   * @param step
   */
  every(step, options) {
    let offset4 = 0;
    let rangeCallback;
    const { snapTo = "start" } = options != null ? options : {};
    if (typeof snapTo === "string") {
      const initialOffset = offset4;
      rangeCallback = (start, stop) => {
        const s = snapTo === "start" ? start : stop;
        offset4 = this.getOffset(s, step);
        return () => offset4 = initialOffset;
      };
    } else if (typeof snapTo === "number") {
      offset4 = this.getOffset(new Date(snapTo), step);
    } else if (snapTo instanceof Date) {
      offset4 = this.getOffset(snapTo, step);
    }
    const encode13 = (date) => {
      const e = this._encode(date);
      return Math.floor((e - offset4) / step);
    };
    const decode13 = (encoded) => {
      return this._decode(encoded * step + offset4);
    };
    return new TimeInterval(encode13, decode13, rangeCallback);
  }
};
function encode(date) {
  return date.getTime();
}
function decode(encoded) {
  return new Date(encoded);
}
var millisecond = new CountableTimeInterval(encode, decode);
var millisecond_default = millisecond;
var epochYear = (/* @__PURE__ */ new Date(0)).getFullYear();
var durationSecond = 1e3;
var durationMinute = durationSecond * 60;
var durationHour = durationMinute * 60;
var durationDay = durationHour * 24;
var durationWeek = durationDay * 7;
var durationMonth = durationDay * 30;
var durationYear = durationDay * 365;
var offset = (/* @__PURE__ */ new Date()).getTimezoneOffset() * durationMinute;
function encode2(date) {
  return Math.floor((date.getTime() - offset) / durationSecond);
}
function decode2(encoded) {
  return new Date(offset + encoded * durationSecond);
}
var second = new CountableTimeInterval(encode2, decode2);
var second_default = second;
var offset2 = (/* @__PURE__ */ new Date()).getTimezoneOffset() * durationMinute;
function encode3(date) {
  return Math.floor((date.getTime() - offset2) / durationMinute);
}
function decode3(encoded) {
  return new Date(offset2 + encoded * durationMinute);
}
var minute = new CountableTimeInterval(encode3, decode3);
var minute_default = minute;
var offset3 = (/* @__PURE__ */ new Date()).getTimezoneOffset() * durationMinute;
function encode4(date) {
  return Math.floor((date.getTime() - offset3) / durationHour);
}
function decode4(encoded) {
  return new Date(offset3 + encoded * durationHour);
}
var hour = new CountableTimeInterval(encode4, decode4);
var hour_default = hour;
function encode5(date) {
  const tzOffsetMs = date.getTimezoneOffset() * durationMinute;
  return Math.floor((date.getTime() - tzOffsetMs) / durationDay);
}
function decode5(encoded) {
  const d = new Date(1970, 0, 1);
  d.setDate(d.getDate() + encoded);
  return d;
}
var day = new CountableTimeInterval(encode5, decode5);
var day_default = day;
function weekday(weekStart) {
  const thursday2 = 4;
  const dayShift = (7 + weekStart - thursday2) % 7;
  function encode13(date) {
    const tzOffsetMs = date.getTimezoneOffset() * durationMinute;
    return Math.floor((date.getTime() - tzOffsetMs) / durationWeek - dayShift / 7);
  }
  function decode13(encoded) {
    const d = new Date(1970, 0, 1);
    d.setDate(d.getDate() + encoded * 7 + dayShift);
    return d;
  }
  return new CountableTimeInterval(encode13, decode13);
}
var sunday = weekday(0);
var monday = weekday(1);
var tuesday = weekday(2);
var wednesday = weekday(3);
var thursday = weekday(4);
var friday = weekday(5);
var saturday = weekday(6);
var week_default = sunday;
function encode6(date) {
  return date.getFullYear() * 12 + date.getMonth();
}
function decode6(encoded) {
  const year2 = Math.floor(encoded / 12);
  const month2 = encoded - year2 * 12;
  return new Date(year2, month2, 1);
}
var month = new CountableTimeInterval(encode6, decode6);
var month_default = month;
function encode7(date) {
  return date.getFullYear();
}
function decode7(encoded) {
  const d = /* @__PURE__ */ new Date();
  d.setFullYear(encoded);
  d.setMonth(0, 1);
  d.setHours(0, 0, 0, 0);
  return d;
}
var year = new CountableTimeInterval(encode7, decode7);
var year_default = year;
function encode8(date) {
  return Math.floor(date.getTime() / durationMinute);
}
function decode8(encoded) {
  return new Date(encoded * durationMinute);
}
var utcMinute = new CountableTimeInterval(encode8, decode8);
function encode9(date) {
  return Math.floor(date.getTime() / durationHour);
}
function decode9(encoded) {
  return new Date(encoded * durationHour);
}
var utcHour = new CountableTimeInterval(encode9, decode9);
function encode10(date) {
  return Math.floor(date.getTime() / durationDay);
}
function decode10(encoded) {
  const d = /* @__PURE__ */ new Date(0);
  d.setUTCDate(d.getUTCDate() + encoded);
  d.setUTCHours(0, 0, 0, 0);
  return d;
}
var utcDay = new CountableTimeInterval(encode10, decode10);
function encode11(date) {
  return date.getUTCFullYear() * 12 + date.getUTCMonth();
}
function decode11(encoded) {
  const year2 = Math.floor(encoded / 12);
  const month2 = encoded - year2 * 12;
  return new Date(Date.UTC(year2, month2, 1));
}
var utcMonth = new CountableTimeInterval(encode11, decode11);
function encode12(date) {
  return date.getUTCFullYear();
}
function decode12(encoded) {
  const d = /* @__PURE__ */ new Date();
  d.setUTCFullYear(encoded);
  d.setUTCMonth(0, 1);
  d.setUTCHours(0, 0, 0, 0);
  return d;
}
var utcYear = new CountableTimeInterval(encode12, decode12);
var enterpriseModule = {
  isEnterprise: false
};
var BaseModuleInstance = class {
  constructor() {
    this.destroyFns = [];
  }
  destroy() {
    for (const destroyFn of this.destroyFns) {
      destroyFn();
    }
  }
};
var REGISTERED_MODULES = [];
function registerModule(module2) {
  const otherModule = REGISTERED_MODULES.find((other) => {
    return module2.type === other.type && module2.optionsKey === other.optionsKey && module2.identifier === other.identifier;
  });
  if (otherModule) {
    if (module2.packageType === "enterprise" && otherModule.packageType === "community") {
      const index = REGISTERED_MODULES.indexOf(otherModule);
      REGISTERED_MODULES.splice(index, 1, module2);
    } else {
    }
  } else {
    REGISTERED_MODULES.push(module2);
  }
}
function hasRegisteredEnterpriseModules() {
  return REGISTERED_MODULES.some((m) => m.packageType === "enterprise");
}
var MODULE_CONFLICTS = /* @__PURE__ */ new Map();
function registerModuleConflicts(source, targets) {
  MODULE_CONFLICTS.set(source, targets);
}
function extent(values) {
  const { length } = values;
  if (length === 0) {
    return void 0;
  }
  let min = Infinity;
  let max = -Infinity;
  for (let i = 0; i < length; i++) {
    let v = values[i];
    if (v instanceof Date) {
      v = v.getTime();
    }
    if (typeof v !== "number") {
      continue;
    }
    if (v < min) {
      min = v;
    }
    if (v > max) {
      max = v;
    }
  }
  const extent2 = [min, max];
  if (extent2.some((v) => !isFinite(v))) {
    return void 0;
  }
  return extent2;
}
function normalisedExtent(d, min, max) {
  return normalisedExtentWithMetadata(d, min, max).extent;
}
function normalisedExtentWithMetadata(d, min, max) {
  var _a;
  let clipped = false;
  if (d.length > 2) {
    d = (_a = extent(d)) != null ? _a : [NaN, NaN];
  }
  if (!isNaN(min)) {
    clipped || (clipped = min > d[0]);
    d = [min, d[1]];
  }
  if (!isNaN(max)) {
    clipped || (clipped = max < d[1]);
    d = [d[0], max];
  }
  if (d[0] > d[1]) {
    d = [];
  }
  return { extent: d, clipped };
}
function arraysEqual(a, b) {
  if (a == null || b == null || a.length !== b.length) {
    return false;
  }
  for (let i = 0; i < a.length; i++) {
    if (Array.isArray(a[i]) && Array.isArray(b[i])) {
      if (!arraysEqual(a[i], b[i])) {
        return false;
      }
    } else if (a[i] !== b[i]) {
      return false;
    }
  }
  return true;
}
function toArray(value) {
  if (typeof value === "undefined") {
    return [];
  }
  return Array.isArray(value) ? value : [value];
}
function unique(array) {
  return Array.from(new Set(array));
}
var doOnceFlags = {};
function doOnce(func, key) {
  if (doOnceFlags[key]) {
    return;
  }
  func();
  doOnceFlags[key] = true;
}
var Logger = {
  log(...logContent) {
    console.log(...logContent);
  },
  warn(message, ...logContent) {
    console.warn(`AG Charts - ${message}`, ...logContent);
  },
  error(message, ...logContent) {
    if (typeof message === "object") {
      console.error(`AG Charts error`, message, ...logContent);
    } else {
      console.error(`AG Charts - ${message}`, ...logContent);
    }
  },
  table(...logContent) {
    console.table(...logContent);
  },
  warnOnce(message, ...logContent) {
    doOnce(() => Logger.warn(message, ...logContent), `Logger.warn: ${message}`);
  },
  errorOnce(message, ...logContent) {
    doOnce(() => Logger.error(message, ...logContent), `Logger.error: ${message}`);
  }
};
function windowValue(name) {
  const WINDOW = typeof window !== "undefined" ? window : (
    // typeof global !== 'undefined' ? (global as any) :
    void 0
  );
  return WINDOW == null ? void 0 : WINDOW[name];
}
var LONG_TIME_PERIOD_THRESHOLD = 2e3;
var timeOfLastLog = Date.now();
var logTimeGap = () => {
  const timeSinceLastLog = Date.now() - timeOfLastLog;
  if (timeSinceLastLog > LONG_TIME_PERIOD_THRESHOLD) {
    const prettyDuration = (Math.floor(timeSinceLastLog / 100) / 10).toFixed(1);
    Logger.log(`**** ${prettyDuration}s since last log message ****`);
  }
  timeOfLastLog = Date.now();
};
var Debug = {
  create(...debugSelectors) {
    return (...logContent) => {
      if (Debug.check(...debugSelectors)) {
        if (typeof logContent[0] === "function") {
          logContent = toArray(logContent[0]());
        }
        logTimeGap();
        Logger.log(...logContent);
      }
    };
  },
  check(...debugSelectors) {
    if (debugSelectors.length === 0) {
      debugSelectors.push(true);
    }
    const chartDebug = toArray(windowValue("agChartsDebug"));
    return chartDebug.some((selector) => debugSelectors.includes(selector));
  }
};
var BREAK_TRANSFORM_CHAIN = Symbol("BREAK");
var CONFIG_KEY = "__decorator_config";
function initialiseConfig(target, propertyKeyOrSymbol) {
  if (Object.getOwnPropertyDescriptor(target, CONFIG_KEY) == null) {
    Object.defineProperty(target, CONFIG_KEY, { value: {} });
  }
  const config = target[CONFIG_KEY];
  const propertyKey = propertyKeyOrSymbol.toString();
  if (typeof config[propertyKey] !== "undefined") {
    return config[propertyKey];
  }
  const valuesMap = /* @__PURE__ */ new WeakMap();
  config[propertyKey] = { setters: [], getters: [], valuesMap };
  const descriptor = Object.getOwnPropertyDescriptor(target, propertyKeyOrSymbol);
  const prevSet = descriptor == null ? void 0 : descriptor.set;
  const prevGet = descriptor == null ? void 0 : descriptor.get;
  const getter = function() {
    let value = prevGet ? prevGet.call(this) : valuesMap.get(this);
    for (const transformFn of config[propertyKey].getters) {
      value = transformFn(this, propertyKeyOrSymbol, value);
      if (value === BREAK_TRANSFORM_CHAIN) {
        return;
      }
    }
    return value;
  };
  const setter = function(value) {
    const { setters } = config[propertyKey];
    let oldValue;
    if (setters.some((f) => f.length > 2)) {
      oldValue = prevGet ? prevGet.call(this) : valuesMap.get(this);
    }
    for (const transformFn of setters) {
      value = transformFn(this, propertyKeyOrSymbol, value, oldValue);
      if (value === BREAK_TRANSFORM_CHAIN) {
        return;
      }
    }
    if (prevSet) {
      prevSet.call(this, value);
    } else {
      valuesMap.set(this, value);
    }
  };
  Object.defineProperty(target, propertyKeyOrSymbol, {
    set: setter,
    get: getter,
    enumerable: true,
    configurable: false
  });
  return config[propertyKey];
}
function addTransformToInstanceProperty(setTransform, getTransform, configMetadata) {
  return (target, propertyKeyOrSymbol) => {
    const config = initialiseConfig(target, propertyKeyOrSymbol);
    config.setters.push(setTransform);
    if (getTransform) {
      config.getters.unshift(getTransform);
    }
    if (configMetadata) {
      Object.assign(config, configMetadata);
    }
  };
}
function isDecoratedObject(target) {
  return typeof target !== "undefined" && CONFIG_KEY in target;
}
function listDecoratedProperties(target) {
  const targets = /* @__PURE__ */ new Set();
  while (isDecoratedObject(target)) {
    targets.add(target == null ? void 0 : target[CONFIG_KEY]);
    target = Object.getPrototypeOf(target);
  }
  return Array.from(targets).flatMap((configMap) => Object.keys(configMap));
}
function extractDecoratedProperties(target) {
  return listDecoratedProperties(target).reduce((result, key) => {
    var _a;
    result[key] = (_a = target[key]) != null ? _a : null;
    return result;
  }, {});
}
function extractDecoratedPropertyMetadata(target, propertyKeyOrSymbol) {
  const propertyKey = propertyKeyOrSymbol.toString();
  while (isDecoratedObject(target)) {
    const config = target[CONFIG_KEY];
    if (Object.hasOwn(config, propertyKey)) {
      return config[propertyKey];
    }
    target = Object.getPrototypeOf(target);
  }
}
function createDeprecationWarning() {
  return (key, message) => {
    const msg = [`Property [${key}] is deprecated.`, message].filter(Boolean).join(" ");
    Logger.warnOnce(msg);
  };
}
function Deprecated(message, opts) {
  const warnDeprecated = createDeprecationWarning();
  const def = opts == null ? void 0 : opts.default;
  return addTransformToInstanceProperty((_, key, value) => {
    if (value !== def) {
      warnDeprecated(key.toString(), message);
    }
    return value;
  });
}
function DeprecatedAndRenamedTo(newPropName, mapValue) {
  const warnDeprecated = createDeprecationWarning();
  return addTransformToInstanceProperty(
    (target, key, value) => {
      if (value !== target[newPropName]) {
        warnDeprecated(key.toString(), `Use [${newPropName}] instead.`);
        target[newPropName] = mapValue ? mapValue(value) : value;
      }
      return BREAK_TRANSFORM_CHAIN;
    },
    (target, key) => {
      warnDeprecated(key.toString(), `Use [${newPropName}] instead.`);
      return target[newPropName];
    }
  );
}
var RedrawType = /* @__PURE__ */ ((RedrawType2) => {
  RedrawType2[RedrawType2["NONE"] = 0] = "NONE";
  RedrawType2[RedrawType2["TRIVIAL"] = 1] = "TRIVIAL";
  RedrawType2[RedrawType2["MINOR"] = 2] = "MINOR";
  RedrawType2[RedrawType2["MAJOR"] = 3] = "MAJOR";
  return RedrawType2;
})(RedrawType || {});
function functionConstructorAvailable() {
  try {
    new Function("return true");
    return true;
  } catch (e) {
    return false;
  }
}
var STRING_FUNCTION_USEABLE = functionConstructorAvailable();
function SceneChangeDetection(opts) {
  const { changeCb, convertor } = opts != null ? opts : {};
  return function(target, key) {
    const privateKey = `__${key}`;
    if (target[key]) {
      return;
    }
    if (STRING_FUNCTION_USEABLE && changeCb == null && convertor == null) {
      prepareFastGetSet(target, key, privateKey, opts);
    } else {
      prepareSlowGetSet(target, key, privateKey, opts);
    }
  };
}
function prepareFastGetSet(target, key, privateKey, opts) {
  const { redraw = 1, type = "normal", checkDirtyOnAssignment = false } = opts != null ? opts : {};
  const setterJs = new Function(
    "value",
    `
        const oldValue = this.${privateKey};
        if (value !== oldValue) {
            this.${privateKey} = value;
            ${type === "normal" ? `this.markDirty(this, ${redraw});` : ""}
            ${type === "transform" ? `this.markDirtyTransform(${redraw});` : ""}
            ${type === "path" ? `if (!this._dirtyPath) { this._dirtyPath = true; this.markDirty(this, ${redraw}); }` : ""}
            ${type === "font" ? `if (!this._dirtyFont) { this._dirtyFont = true; this.markDirty(this, ${redraw}); }` : ""}
        }
        ${checkDirtyOnAssignment ? `if (value != null && value._dirty > ${0}) { this.markDirty(value, value._dirty); }` : ""}
`
  );
  const getterJs = new Function(`return this.${privateKey};`);
  Object.defineProperty(target, key, {
    set: setterJs,
    get: getterJs,
    enumerable: true,
    configurable: true
  });
}
function prepareSlowGetSet(target, key, privateKey, opts) {
  const {
    redraw = 1,
    type = "normal",
    changeCb,
    convertor,
    checkDirtyOnAssignment = false
  } = opts != null ? opts : {};
  const setter = function(value) {
    const oldValue = this[privateKey];
    value = convertor ? convertor(value) : value;
    if (value !== oldValue) {
      this[privateKey] = value;
      if (type === "normal")
        this.markDirty(this, redraw);
      if (type === "transform")
        this.markDirtyTransform(redraw);
      if (type === "path" && !this._dirtyPath) {
        this._dirtyPath = true;
        this.markDirty(this, redraw);
      }
      if (type === "font" && !this._dirtyFont) {
        this._dirtyFont = true;
        this.markDirty(this, redraw);
      }
      if (changeCb)
        changeCb(this);
    }
    if (checkDirtyOnAssignment && value != null && value._dirty > 0)
      this.markDirty(value, value._dirty);
  };
  const getter = function() {
    return this[privateKey];
  };
  Object.defineProperty(target, key, {
    set: setter,
    get: getter,
    enumerable: true,
    configurable: true
  });
}
var ChangeDetectable = class {
  constructor() {
    this._dirty = 3;
  }
  markDirty(_source, type = 1) {
    if (this._dirty > type) {
      return;
    }
    this._dirty = type;
  }
  markClean(_opts) {
    this._dirty = 0;
  }
  isDirty() {
    return this._dirty > 0;
  }
};
function isDefined(val) {
  return val != null;
}
function isArray(value) {
  return Array.isArray(value);
}
function isBoolean(value) {
  return typeof value === "boolean";
}
function isDate(value) {
  return value instanceof Date;
}
function isValidDate(value) {
  return isDate(value) && !isNaN(Number(value));
}
function isFunction(value) {
  return typeof value === "function";
}
function isObject(value) {
  return typeof value === "object" && value !== null && !isArray(value);
}
function isObjectLike(value) {
  return typeof value === "object" && value !== null;
}
function isPlainObject(value) {
  return typeof value === "object" && value !== null && value.constructor === Object;
}
function isString(value) {
  return typeof value === "string";
}
function isNumber(value) {
  return typeof value === "number";
}
function isFiniteNumber(value) {
  return isNumber(value) && Number.isFinite(value);
}
function isHtmlElement(value) {
  return typeof window !== "undefined" && value instanceof HTMLElement;
}
var BaseProperties = class extends ChangeDetectable {
  constructor(className) {
    super();
    this.className = className;
  }
  set(properties) {
    const keys = new Set(Object.keys(properties));
    for (const propertyKey of listDecoratedProperties(this)) {
      if (keys.has(propertyKey)) {
        const value = properties[propertyKey];
        const self = this;
        if (isProperties(self[propertyKey])) {
          self[propertyKey] = self[propertyKey] instanceof PropertiesArray ? self[propertyKey].reset(value) : self[propertyKey].set(value);
        } else {
          self[propertyKey] = value;
        }
        keys.delete(propertyKey);
      }
    }
    for (const unknownKey of keys) {
      const { className = this.constructor.name } = this;
      Logger.warn(`unable to set [${unknownKey}] in ${className} - property is unknown`);
    }
    return this;
  }
  isValid() {
    return listDecoratedProperties(this).every((propertyKey) => {
      const { optional } = extractDecoratedPropertyMetadata(this, propertyKey);
      return optional || typeof this[propertyKey] !== "undefined";
    });
  }
  toJson() {
    return listDecoratedProperties(this).reduce((object, propertyKey) => {
      object[propertyKey] = this[propertyKey];
      return object;
    }, {});
  }
};
var PropertiesArray = class _PropertiesArray extends Array {
  constructor(itemFactory, ...properties) {
    super(properties.length);
    Object.defineProperty(this, "itemFactory", { value: itemFactory, enumerable: false, configurable: false });
    this.set(properties);
  }
  set(properties) {
    if (isArray(properties)) {
      this.length = properties.length;
      for (let i = 0; i < properties.length; i++) {
        this[i] = new this.itemFactory().set(properties[i]);
      }
    }
    return this;
  }
  reset(properties) {
    return new _PropertiesArray(this.itemFactory, ...properties);
  }
};
function isProperties(value) {
  return value instanceof BaseProperties || value instanceof PropertiesArray;
}
var CLASS_INSTANCE_TYPE = "class-instance";
function jsonDiff(source, target) {
  if (isArray(target)) {
    if (!isArray(source) || source.length !== target.length || target.some((v, i) => jsonDiff(source[i], v) != null)) {
      return target;
    }
  } else if (isObject(target)) {
    if (!isObject(source) || !isPlainObject(target)) {
      return target;
    }
    const result = {};
    const allKeys = /* @__PURE__ */ new Set([
      ...Object.keys(source),
      ...Object.keys(target)
    ]);
    for (const key of allKeys) {
      if (source[key] === target[key]) {
        continue;
      }
      if (typeof source[key] !== typeof target[key]) {
        result[key] = target[key];
      } else {
        const diff2 = jsonDiff(source[key], target[key]);
        if (diff2 !== null) {
          result[key] = diff2;
        }
      }
    }
    return Object.keys(result).length ? result : null;
  } else if (source !== target) {
    return target;
  }
  return null;
}
function jsonClone(source) {
  if (isArray(source)) {
    return source.map(jsonClone);
  }
  if (isPlainObject(source)) {
    return Object.entries(source).reduce((result, [key, value]) => {
      result[key] = jsonClone(value);
      return result;
    }, {});
  }
  return source;
}
var DELETE = Symbol("<delete-property>");
var NOT_SPECIFIED = Symbol("<unspecified-property>");
function jsonMerge(json, opts) {
  var _a;
  const avoidDeepClone = (_a = opts == null ? void 0 : opts.avoidDeepClone) != null ? _a : [];
  const jsonTypes = json.map((v) => classify(v));
  if (jsonTypes.some((v) => v === "array")) {
    const finalValue = json[json.length - 1];
    if (Array.isArray(finalValue)) {
      return finalValue.map((v) => {
        const type = classify(v);
        if (type === "array")
          return jsonMerge([[], v], opts);
        if (type === "object")
          return jsonMerge([{}, v], opts);
        return v;
      });
    }
    return finalValue;
  }
  const result = {};
  const props = new Set(json.map((v) => v != null ? Object.keys(v) : []).reduce((r, n) => r.concat(n), []));
  for (const nextProp of props) {
    const values = json.map((j) => {
      if (j != null && typeof j === "object" && nextProp in j) {
        return j[nextProp];
      }
      return NOT_SPECIFIED;
    }).filter((v) => v !== NOT_SPECIFIED);
    if (values.length === 0) {
      continue;
    }
    const lastValue = values[values.length - 1];
    if (lastValue === DELETE) {
      continue;
    }
    const types = values.map((v) => classify(v));
    const type = types[0];
    if (types.some((t) => t !== type)) {
      result[nextProp] = lastValue;
      continue;
    }
    if ((type === "array" || type === "object") && !avoidDeepClone.includes(nextProp)) {
      result[nextProp] = jsonMerge(values, opts);
    } else if (type === "array") {
      result[nextProp] = [...lastValue];
    } else {
      result[nextProp] = lastValue;
    }
  }
  return result;
}
function jsonApply(target, source, params = {}) {
  var _a, _b, _c;
  const {
    path,
    matcherPath = path ? path.replace(/(\[[0-9+]+])/i, "[]") : void 0,
    skip = [],
    constructors = {},
    constructedArrays = /* @__PURE__ */ new WeakMap(),
    allowedTypes = {},
    idx
  } = params;
  if (target == null) {
    throw new Error(`AG Charts - target is uninitialised: ${path != null ? path : "<root>"}`);
  }
  if (source == null) {
    return target;
  }
  if (isProperties(target)) {
    return target.set(source);
  }
  const targetAny = target;
  if (idx != null && "_declarationOrder" in targetAny) {
    targetAny["_declarationOrder"] = idx;
  }
  const targetType = classify(target);
  for (const property in source) {
    const propertyMatcherPath = `${matcherPath ? matcherPath + "." : ""}${property}`;
    if (skip.indexOf(propertyMatcherPath) >= 0) {
      continue;
    }
    const newValue = source[property];
    const propertyPath = `${path ? path + "." : ""}${property}`;
    const targetClass = targetAny.constructor;
    const currentValue = targetAny[property];
    let ctr = (_a = constructors[propertyMatcherPath]) != null ? _a : constructors[property];
    try {
      const currentValueType = classify(currentValue);
      const newValueType = classify(newValue);
      if (targetType === CLASS_INSTANCE_TYPE && !(property in target || Object.hasOwn(targetAny, property))) {
        Logger.warn(`unable to set [${propertyPath}] in ${targetClass == null ? void 0 : targetClass.name} - property is unknown`);
        continue;
      }
      const allowableTypes = (_b = allowedTypes[propertyMatcherPath]) != null ? _b : [currentValueType];
      if (currentValueType === CLASS_INSTANCE_TYPE && newValueType === "object") {
      } else if (currentValueType != null && newValueType != null && !allowableTypes.includes(newValueType)) {
        Logger.warn(
          `unable to set [${propertyPath}] in ${targetClass == null ? void 0 : targetClass.name} - can't apply type of [${newValueType}], allowed types are: [${allowableTypes}]`
        );
        continue;
      }
      if (newValueType === "array") {
        ctr = (_c = ctr != null ? ctr : constructedArrays.get(currentValue)) != null ? _c : constructors[`${propertyMatcherPath}[]`];
        if (isProperties(targetAny[property])) {
          targetAny[property].set(newValue);
        } else if (ctr != null) {
          const newValueArray = newValue;
          targetAny[property] = newValueArray.map(
            (v, idx2) => jsonApply(new ctr(), v, __spreadProps(__spreadValues({}, params), {
              path: propertyPath,
              matcherPath: propertyMatcherPath + "[]",
              idx: idx2
            }))
          );
        } else {
          targetAny[property] = newValue;
        }
      } else if (newValueType === CLASS_INSTANCE_TYPE) {
        targetAny[property] = newValue;
      } else if (newValueType === "object") {
        if (currentValue != null) {
          jsonApply(currentValue, newValue, __spreadProps(__spreadValues({}, params), {
            path: propertyPath,
            matcherPath: propertyMatcherPath,
            idx: void 0
          }));
        } else if (isProperties(targetAny[property])) {
          targetAny[property].set(newValue);
        } else if (ctr != null) {
          const obj = new ctr();
          if (isProperties(obj)) {
            targetAny[property] = obj.set(newValue);
          } else {
            targetAny[property] = jsonApply(obj, newValue, __spreadProps(__spreadValues({}, params), {
              path: propertyPath,
              matcherPath: propertyMatcherPath,
              idx: void 0
            }));
          }
        } else {
          targetAny[property] = newValue;
        }
      } else if (isProperties(targetAny[property])) {
        targetAny[property].set(newValue);
      } else {
        targetAny[property] = newValue;
      }
    } catch (error) {
      Logger.warn(`unable to set [${propertyPath}] in [${targetClass == null ? void 0 : targetClass.name}]; nested error is: ${error.message}`);
    }
  }
  return target;
}
function jsonWalk(json, visit, opts, ...jsons) {
  var _a;
  if (isArray(json)) {
    visit(json, ...jsons);
    json.forEach((node, index) => {
      jsonWalk(node, visit, opts, ...keyMapper(jsons, index));
    });
  } else if (isPlainObject(json)) {
    visit(json, ...jsons);
    for (const key of Object.keys(json)) {
      if ((_a = opts == null ? void 0 : opts.skip) == null ? void 0 : _a.includes(key)) {
        continue;
      }
      const value = json[key];
      if (isArray(value) || isPlainObject(value)) {
        jsonWalk(value, visit, opts, ...keyMapper(jsons, key));
      }
    }
  }
}
function keyMapper(data, key) {
  return data.map((dataObject) => dataObject == null ? void 0 : dataObject[key]);
}
function classify(value) {
  if (value == null) {
    return null;
  }
  if (isHtmlElement(value) || isDate(value)) {
    return "primitive";
  }
  if (isArray(value)) {
    return "array";
  }
  if (isObject(value)) {
    return isPlainObject(value) ? "object" : CLASS_INSTANCE_TYPE;
  }
  if (isFunction(value)) {
    return "function";
  }
  return "primitive";
}
var twoPi = Math.PI * 2;
function normalizeAngle360(radians) {
  radians %= twoPi;
  radians += twoPi;
  radians %= twoPi;
  return radians;
}
function normalizeAngle360Inclusive(radians) {
  radians %= twoPi;
  radians += twoPi;
  if (radians !== twoPi) {
    radians %= twoPi;
  }
  return radians;
}
function normalizeAngle180(radians) {
  radians %= twoPi;
  if (radians < -Math.PI) {
    radians += twoPi;
  } else if (radians >= Math.PI) {
    radians -= twoPi;
  }
  return radians;
}
function toRadians(degrees) {
  return degrees / 180 * Math.PI;
}
function toDegrees(radians) {
  return radians / Math.PI * 180;
}
function angleBetween(angle0, angle1) {
  angle0 = normalizeAngle360(angle0);
  angle1 = normalizeAngle360(angle1);
  return angle1 - angle0 + (angle0 > angle1 ? 2 * Math.PI : 0);
}
var Invalidating = (target, propertyKey) => {
  const mappedProperty = Symbol(String(propertyKey));
  target[mappedProperty] = void 0;
  Object.defineProperty(target, propertyKey, {
    get() {
      return this[mappedProperty];
    },
    set(newValue) {
      const oldValue = this[mappedProperty];
      if (oldValue !== newValue) {
        this[mappedProperty] = newValue;
        this.invalid = true;
      }
    },
    enumerable: true,
    configurable: false
  });
};
function clamp(x, min, max) {
  return Math.max(min, Math.min(max, x));
}
var BandScale = class {
  constructor() {
    this.type = "band";
    this.invalid = true;
    this.interval = 1;
    this.index = /* @__PURE__ */ new Map();
    this.ordinalRange = [];
    this._domain = [];
    this.range = [0, 1];
    this._bandwidth = 1;
    this._step = 1;
    this._rawBandwidth = 1;
    this._paddingInner = 0;
    this._paddingOuter = 0;
    this.round = false;
  }
  refresh() {
    if (!this.invalid)
      return;
    this.invalid = false;
    this.update();
    if (this.invalid) {
      Logger.warnOnce("Expected update to not invalidate scale");
    }
  }
  set domain(values) {
    this.invalid = true;
    const domain = [];
    this.index = /* @__PURE__ */ new Map();
    const index = this.index;
    values.forEach((value) => {
      if (index.get(value) === void 0) {
        index.set(value, domain.push(value) - 1);
      }
    });
    this._domain = domain;
  }
  get domain() {
    return this._domain;
  }
  ticks() {
    this.refresh();
    const { interval = 1 } = this;
    const step = Math.abs(Math.round(interval));
    return this._domain.filter((_, i) => i % step === 0);
  }
  convert(d) {
    this.refresh();
    const i = this.index.get(d);
    if (i === void 0) {
      return NaN;
    }
    const r = this.ordinalRange[i];
    if (r === void 0) {
      return NaN;
    }
    return r;
  }
  invert(position) {
    this.refresh();
    const index = this.ordinalRange.findIndex((p) => p === position);
    return this.domain[index];
  }
  get bandwidth() {
    this.refresh();
    return this._bandwidth;
  }
  get step() {
    this.refresh();
    return this._step;
  }
  get rawBandwidth() {
    this.refresh();
    return this._rawBandwidth;
  }
  set padding(value) {
    value = clamp(value, 0, 1);
    this._paddingInner = value;
    this._paddingOuter = value;
  }
  get padding() {
    return this._paddingInner;
  }
  set paddingInner(value) {
    this._paddingInner = clamp(value, 0, 1);
  }
  get paddingInner() {
    return this._paddingInner;
  }
  set paddingOuter(value) {
    this._paddingOuter = clamp(value, 0, 1);
  }
  get paddingOuter() {
    return this._paddingOuter;
  }
  update() {
    const count2 = this._domain.length;
    if (count2 === 0) {
      return;
    }
    const round3 = this.round;
    const paddingInner = this._paddingInner;
    const paddingOuter = this._paddingOuter;
    const [r0, r1] = this.range;
    const width = r1 - r0;
    const rawStep = width / Math.max(1, count2 + 2 * paddingOuter - paddingInner);
    const step = round3 ? Math.floor(rawStep) : rawStep;
    const fullBandWidth = step * (count2 - paddingInner);
    const x0 = r0 + (width - fullBandWidth) / 2;
    const start = round3 ? Math.round(x0) : x0;
    const bw = step * (1 - paddingInner);
    const bandwidth = round3 ? Math.round(bw) : bw;
    const rawBandwidth = rawStep * (1 - paddingInner);
    const values = [];
    for (let i = 0; i < count2; i++) {
      values.push(start + step * i);
    }
    this._bandwidth = bandwidth;
    this._rawBandwidth = rawBandwidth;
    this._step = step;
    this.ordinalRange = values;
  }
};
__decorateClass([
  Invalidating
], BandScale.prototype, "interval", 2);
__decorateClass([
  Invalidating
], BandScale.prototype, "range", 2);
__decorateClass([
  Invalidating
], BandScale.prototype, "round", 2);
function clamp2(min, value, max) {
  return Math.min(max, Math.max(min, value));
}
function clampArray(value, array) {
  return clamp2(Math.min(...array), value, Math.max(...array));
}
function isEqual(a, b, epsilon2 = 1e-10) {
  return Math.abs(a - b) < epsilon2;
}
function isNegative(a) {
  return Math.sign(a) < 0 || Object.is(a, -0);
}
function isReal(a) {
  return isFinite(a) && !isNaN(a);
}
function round(value, decimals = 2) {
  const pow = Math.pow(10, decimals);
  return Math.round(value * pow) / pow;
}
function toFixed(value, fractionOrSignificantDigits = 2) {
  const power = Math.floor(Math.log(Math.abs(value)) / Math.LN10);
  if (power >= 0 || !isFinite(power)) {
    return value.toFixed(fractionOrSignificantDigits);
  }
  return value.toFixed(Math.abs(power) - 1 + fractionOrSignificantDigits);
}
function toReal(value) {
  return isReal(value) ? value : 0;
}
function mod(n, m) {
  if (n >= 0) {
    return Math.floor(n % m);
  }
  return Math.floor(n % m + m);
}
var countFractionDigits = (value, maxFractionDigits = 10) => {
  const decimal = (Math.abs(value) % 1).toFixed(maxFractionDigits);
  for (let i = decimal.length - 1; i >= 2; i -= 1) {
    if (decimal[i] !== "0") {
      return maxFractionDigits - (decimal.length - 1 - i);
    }
  }
  return 0;
};
var srgbToLinear = (value) => {
  const sign = value < 0 ? -1 : 1;
  const abs = Math.abs(value);
  if (abs <= 0.04045)
    return value / 12.92;
  return sign * __pow((abs + 0.055) / 1.055, 2.4);
};
var srgbFromLinear = (value) => {
  const sign = value < 0 ? -1 : 1;
  const abs = Math.abs(value);
  if (abs > 31308e-7) {
    return sign * (1.055 * __pow(abs, 1 / 2.4) - 0.055);
  }
  return 12.92 * value;
};
var _Color = class _Color2 {
  /**
   * Every color component should be in the [0, 1] range.
   * Some easing functions (such as elastic easing) can overshoot the target value by some amount.
   * So, when animating colors, if the source or target color components are already near
   * or at the edge of the allowed [0, 1] range, it is possible for the intermediate color
   * component value to end up outside of that range mid-animation. For this reason the constructor
   * performs range checking/constraining.
   * @param r Red component.
   * @param g Green component.
   * @param b Blue component.
   * @param a Alpha (opacity) component.
   */
  constructor(r, g, b, a = 1) {
    this.r = clamp2(0, r || 0, 1);
    this.g = clamp2(0, g || 0, 1);
    this.b = clamp2(0, b || 0, 1);
    this.a = clamp2(0, a || 0, 1);
  }
  /**
   * A color string can be in one of the following formats to be valid:
   * - #rgb
   * - #rrggbb
   * - rgb(r, g, b)
   * - rgba(r, g, b, a)
   * - CSS color name such as 'white', 'orange', 'cyan', etc.
   */
  static validColorString(str) {
    if (str.indexOf("#") >= 0) {
      return !!_Color2.parseHex(str);
    }
    if (str.indexOf("rgb") >= 0) {
      return !!_Color2.stringToRgba(str);
    }
    return !!_Color2.nameToHex[str.toLowerCase()];
  }
  /**
   * The given string can be in one of the following formats:
   * - #rgb
   * - #rrggbb
   * - rgb(r, g, b)
   * - rgba(r, g, b, a)
   * - CSS color name such as 'white', 'orange', 'cyan', etc.
   * @param str
   */
  static fromString(str) {
    if (str.indexOf("#") >= 0) {
      return _Color2.fromHexString(str);
    }
    const hex = _Color2.nameToHex[str.toLowerCase()];
    if (hex) {
      return _Color2.fromHexString(hex);
    }
    if (str.indexOf("rgb") >= 0) {
      return _Color2.fromRgbaString(str);
    }
    throw new Error(`Invalid color string: '${str}'`);
  }
  static tryParseFromString(str) {
    try {
      return _Color2.fromString(str);
    } catch (e) {
      Logger.warnOnce(`invalid color string: '${str}'.`);
      return _Color2.fromArray([0, 0, 0]);
    }
  }
  // See https://drafts.csswg.org/css-color/#hex-notation
  static parseHex(input) {
    input = input.replace(/ /g, "").slice(1);
    let parts;
    switch (input.length) {
      case 6:
      case 8:
        parts = [];
        for (let i = 0; i < input.length; i += 2) {
          parts.push(parseInt(`${input[i]}${input[i + 1]}`, 16));
        }
        break;
      case 3:
      case 4:
        parts = input.split("").map((p) => parseInt(p, 16)).map((p) => p + p * 16);
        break;
    }
    if ((parts == null ? void 0 : parts.length) >= 3 && parts.every((p) => p >= 0)) {
      if (parts.length === 3) {
        parts.push(255);
      }
      return parts;
    }
  }
  static fromHexString(str) {
    const values = _Color2.parseHex(str);
    if (values) {
      const [r, g, b, a] = values;
      return new _Color2(r / 255, g / 255, b / 255, a / 255);
    }
    throw new Error(`Malformed hexadecimal color string: '${str}'`);
  }
  static stringToRgba(str) {
    let [po, pc] = [NaN, NaN];
    for (let i = 0; i < str.length; i++) {
      const c = str[i];
      if (!po && c === "(") {
        po = i;
      } else if (c === ")") {
        pc = i;
        break;
      }
    }
    const contents = po && pc && str.substring(po + 1, pc);
    if (!contents) {
      return;
    }
    const parts = contents.split(",");
    const rgba = [];
    for (let i = 0; i < parts.length; i++) {
      const part = parts[i];
      let value = parseFloat(part);
      if (isNaN(value)) {
        return;
      }
      if (part.indexOf("%") >= 0) {
        value = Math.max(0, Math.min(100, value));
        value /= 100;
      } else {
        if (i === 3) {
          value = Math.max(0, Math.min(1, value));
        } else {
          value = Math.max(0, Math.min(255, value));
          value /= 255;
        }
      }
      rgba.push(value);
    }
    return rgba;
  }
  static fromRgbaString(str) {
    const rgba = _Color2.stringToRgba(str);
    if (rgba) {
      if (rgba.length === 3) {
        return new _Color2(rgba[0], rgba[1], rgba[2]);
      } else if (rgba.length === 4) {
        return new _Color2(rgba[0], rgba[1], rgba[2], rgba[3]);
      }
    }
    throw new Error(`Malformed rgb/rgba color string: '${str}'`);
  }
  static fromArray(arr) {
    if (arr.length === 4) {
      return new _Color2(arr[0], arr[1], arr[2], arr[3]);
    }
    if (arr.length === 3) {
      return new _Color2(arr[0], arr[1], arr[2]);
    }
    throw new Error("The given array should contain 3 or 4 color components (numbers).");
  }
  static fromHSB(h, s, b, alpha = 1) {
    const rgb = _Color2.HSBtoRGB(h, s, b);
    return new _Color2(rgb[0], rgb[1], rgb[2], alpha);
  }
  static fromHSL(h, s, l, alpha = 1) {
    const rgb = _Color2.HSLtoRGB(h, s, l);
    return new _Color2(rgb[0], rgb[1], rgb[2], alpha);
  }
  static fromOKLCH(l, c, h, alpha = 1) {
    const rgb = _Color2.OKLCHtoRGB(l, c, h);
    return new _Color2(rgb[0], rgb[1], rgb[2], alpha);
  }
  static padHex(str) {
    return str.length === 1 ? "0" + str : str;
  }
  toHexString() {
    let hex = "#" + _Color2.padHex(Math.round(this.r * 255).toString(16)) + _Color2.padHex(Math.round(this.g * 255).toString(16)) + _Color2.padHex(Math.round(this.b * 255).toString(16));
    if (this.a < 1) {
      hex += _Color2.padHex(Math.round(this.a * 255).toString(16));
    }
    return hex;
  }
  toRgbaString(fractionDigits = 3) {
    const components = [Math.round(this.r * 255), Math.round(this.g * 255), Math.round(this.b * 255)];
    const k = Math.pow(10, fractionDigits);
    if (this.a !== 1) {
      components.push(Math.round(this.a * k) / k);
      return `rgba(${components.join(", ")})`;
    }
    return `rgb(${components.join(", ")})`;
  }
  toString() {
    if (this.a === 1) {
      return this.toHexString();
    }
    return this.toRgbaString();
  }
  toHSB() {
    return _Color2.RGBtoHSB(this.r, this.g, this.b);
  }
  static RGBtoOKLCH(r, g, b) {
    const LSRGB0 = srgbToLinear(r);
    const LSRGB1 = srgbToLinear(g);
    const LSRGB2 = srgbToLinear(b);
    const LMS0 = Math.cbrt(0.4122214708 * LSRGB0 + 0.5363325363 * LSRGB1 + 0.0514459929 * LSRGB2);
    const LMS1 = Math.cbrt(0.2119034982 * LSRGB0 + 0.6806995451 * LSRGB1 + 0.1073969566 * LSRGB2);
    const LMS2 = Math.cbrt(0.0883024619 * LSRGB0 + 0.2817188376 * LSRGB1 + 0.6299787005 * LSRGB2);
    const OKLAB0 = 0.2104542553 * LMS0 + 0.793617785 * LMS1 - 0.0040720468 * LMS2;
    const OKLAB1 = 1.9779984951 * LMS0 - 2.428592205 * LMS1 + 0.4505937099 * LMS2;
    const OKLAB2 = 0.0259040371 * LMS0 + 0.7827717662 * LMS1 - 0.808675766 * LMS2;
    const hue = Math.atan2(OKLAB2, OKLAB1) * 180 / Math.PI;
    const OKLCH0 = OKLAB0;
    const OKLCH1 = Math.hypot(OKLAB1, OKLAB2);
    const OKLCH2 = hue >= 0 ? hue : hue + 360;
    return [OKLCH0, OKLCH1, OKLCH2];
  }
  static OKLCHtoRGB(l, c, h) {
    const OKLAB0 = l;
    const OKLAB1 = c * Math.cos(h * Math.PI / 180);
    const OKLAB2 = c * Math.sin(h * Math.PI / 180);
    const LMS0 = __pow(OKLAB0 + 0.3963377774 * OKLAB1 + 0.2158037573 * OKLAB2, 3);
    const LMS1 = __pow(OKLAB0 - 0.1055613458 * OKLAB1 - 0.0638541728 * OKLAB2, 3);
    const LMS2 = __pow(OKLAB0 - 0.0894841775 * OKLAB1 - 1.291485548 * OKLAB2, 3);
    const LSRGB0 = 4.0767416621 * LMS0 - 3.3077115913 * LMS1 + 0.2309699292 * LMS2;
    const LSRGB1 = -1.2684380046 * LMS0 + 2.6097574011 * LMS1 - 0.3413193965 * LMS2;
    const LSRGB2 = -0.0041960863 * LMS0 - 0.7034186147 * LMS1 + 1.707614701 * LMS2;
    const SRGB0 = srgbFromLinear(LSRGB0);
    const SRGB1 = srgbFromLinear(LSRGB1);
    const SRGB2 = srgbFromLinear(LSRGB2);
    return [SRGB0, SRGB1, SRGB2];
  }
  static RGBtoHSL(r, g, b) {
    const min = Math.min(r, g, b);
    const max = Math.max(r, g, b);
    const l = (max + min) / 2;
    let h;
    let s;
    if (max === min) {
      h = NaN;
      s = 0;
    } else {
      const delta = max - min;
      s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
      if (max === r) {
        h = (g - b) / delta + (g < b ? 6 : 0);
      } else if (max === g) {
        h = (b - r) / delta + 2;
      } else {
        h = (r - g) / delta + 4;
      }
      h *= 360 / 6;
    }
    return [h, s, l];
  }
  static HSLtoRGB(h, s, l) {
    if (s === 0) {
      return [l, l, l];
    }
    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    const p = 2 * l - q;
    function hueToRgb(t) {
      if (t < 0)
        t += 1;
      if (t > 1)
        t -= 1;
      if (t < 1 / 6)
        return p + (q - p) * 6 * t;
      if (t < 1 / 2)
        return q;
      if (t < 2 / 3)
        return p + (q - p) * (2 / 3 - t) * 6;
      return p;
    }
    const r = hueToRgb(h / 360 + 1 / 3);
    const g = hueToRgb(h / 360);
    const b = hueToRgb(h / 360 - 1 / 3);
    return [r, g, b];
  }
  /**
   * Converts the given RGB triple to an array of HSB (HSV) components.
   * The hue component will be `NaN` for achromatic colors.
   */
  static RGBtoHSB(r, g, b) {
    const min = Math.min(r, g, b);
    const max = Math.max(r, g, b);
    const S = max !== 0 ? (max - min) / max : 0;
    let H = NaN;
    if (min !== max) {
      const delta = max - min;
      const rc = (max - r) / delta;
      const gc = (max - g) / delta;
      const bc = (max - b) / delta;
      if (r === max) {
        H = bc - gc;
      } else if (g === max) {
        H = 2 + rc - bc;
      } else {
        H = 4 + gc - rc;
      }
      H /= 6;
      if (H < 0) {
        H = H + 1;
      }
    }
    return [H * 360, S, max];
  }
  /**
   * Converts the given HSB (HSV) triple to an array of RGB components.
   */
  static HSBtoRGB(H, S, B) {
    if (isNaN(H)) {
      H = 0;
    }
    H = (H % 360 + 360) % 360 / 360;
    let r = 0;
    let g = 0;
    let b = 0;
    if (S === 0) {
      r = g = b = B;
    } else {
      const h = (H - Math.floor(H)) * 6;
      const f = h - Math.floor(h);
      const p = B * (1 - S);
      const q = B * (1 - S * f);
      const t = B * (1 - S * (1 - f));
      switch (h >> 0) {
        case 0:
          r = B;
          g = t;
          b = p;
          break;
        case 1:
          r = q;
          g = B;
          b = p;
          break;
        case 2:
          r = p;
          g = B;
          b = t;
          break;
        case 3:
          r = p;
          g = q;
          b = B;
          break;
        case 4:
          r = t;
          g = p;
          b = B;
          break;
        case 5:
          r = B;
          g = p;
          b = q;
          break;
      }
    }
    return [r, g, b];
  }
  derive(hueShift, saturationFactor, brightnessFactor, opacityFactor) {
    const hsb = _Color2.RGBtoHSB(this.r, this.g, this.b);
    let b = hsb[2];
    if (b == 0 && brightnessFactor > 1) {
      b = 0.05;
    }
    const h = ((hsb[0] + hueShift) % 360 + 360) % 360;
    const s = Math.max(Math.min(hsb[1] * saturationFactor, 1), 0);
    b = Math.max(Math.min(b * brightnessFactor, 1), 0);
    const a = Math.max(Math.min(this.a * opacityFactor, 1), 0);
    const rgba = _Color2.HSBtoRGB(h, s, b);
    rgba.push(a);
    return _Color2.fromArray(rgba);
  }
  brighter() {
    return this.derive(0, 1, 1 / 0.7, 1);
  }
  darker() {
    return this.derive(0, 1, 0.7, 1);
  }
  static interpolate(color, other) {
    const c0 = _Color2.tryParseFromString(color);
    const c1 = _Color2.tryParseFromString(other);
    return (t) => {
      const i = (x, y) => x * (1 - t) + y * t;
      const c = new _Color2(i(c0.r, c1.r), i(c0.g, c1.g), i(c0.b, c1.b), i(c0.a, c1.a));
      return c.toString();
    };
  }
};
_Color.didDebug = false;
_Color.nameToHex = Object.freeze({
  aliceblue: "#F0F8FF",
  antiquewhite: "#FAEBD7",
  aqua: "#00FFFF",
  aquamarine: "#7FFFD4",
  azure: "#F0FFFF",
  beige: "#F5F5DC",
  bisque: "#FFE4C4",
  black: "#000000",
  blanchedalmond: "#FFEBCD",
  blue: "#0000FF",
  blueviolet: "#8A2BE2",
  brown: "#A52A2A",
  burlywood: "#DEB887",
  cadetblue: "#5F9EA0",
  chartreuse: "#7FFF00",
  chocolate: "#D2691E",
  coral: "#FF7F50",
  cornflowerblue: "#6495ED",
  cornsilk: "#FFF8DC",
  crimson: "#DC143C",
  cyan: "#00FFFF",
  darkblue: "#00008B",
  darkcyan: "#008B8B",
  darkgoldenrod: "#B8860B",
  darkgray: "#A9A9A9",
  darkgreen: "#006400",
  darkgrey: "#A9A9A9",
  darkkhaki: "#BDB76B",
  darkmagenta: "#8B008B",
  darkolivegreen: "#556B2F",
  darkorange: "#FF8C00",
  darkorchid: "#9932CC",
  darkred: "#8B0000",
  darksalmon: "#E9967A",
  darkseagreen: "#8FBC8F",
  darkslateblue: "#483D8B",
  darkslategray: "#2F4F4F",
  darkslategrey: "#2F4F4F",
  darkturquoise: "#00CED1",
  darkviolet: "#9400D3",
  deeppink: "#FF1493",
  deepskyblue: "#00BFFF",
  dimgray: "#696969",
  dimgrey: "#696969",
  dodgerblue: "#1E90FF",
  firebrick: "#B22222",
  floralwhite: "#FFFAF0",
  forestgreen: "#228B22",
  fuchsia: "#FF00FF",
  gainsboro: "#DCDCDC",
  ghostwhite: "#F8F8FF",
  gold: "#FFD700",
  goldenrod: "#DAA520",
  gray: "#808080",
  green: "#008000",
  greenyellow: "#ADFF2F",
  grey: "#808080",
  honeydew: "#F0FFF0",
  hotpink: "#FF69B4",
  indianred: "#CD5C5C",
  indigo: "#4B0082",
  ivory: "#FFFFF0",
  khaki: "#F0E68C",
  lavender: "#E6E6FA",
  lavenderblush: "#FFF0F5",
  lawngreen: "#7CFC00",
  lemonchiffon: "#FFFACD",
  lightblue: "#ADD8E6",
  lightcoral: "#F08080",
  lightcyan: "#E0FFFF",
  lightgoldenrodyellow: "#FAFAD2",
  lightgray: "#D3D3D3",
  lightgreen: "#90EE90",
  lightgrey: "#D3D3D3",
  lightpink: "#FFB6C1",
  lightsalmon: "#FFA07A",
  lightseagreen: "#20B2AA",
  lightskyblue: "#87CEFA",
  lightslategray: "#778899",
  lightslategrey: "#778899",
  lightsteelblue: "#B0C4DE",
  lightyellow: "#FFFFE0",
  lime: "#00FF00",
  limegreen: "#32CD32",
  linen: "#FAF0E6",
  magenta: "#FF00FF",
  maroon: "#800000",
  mediumaquamarine: "#66CDAA",
  mediumblue: "#0000CD",
  mediumorchid: "#BA55D3",
  mediumpurple: "#9370DB",
  mediumseagreen: "#3CB371",
  mediumslateblue: "#7B68EE",
  mediumspringgreen: "#00FA9A",
  mediumturquoise: "#48D1CC",
  mediumvioletred: "#C71585",
  midnightblue: "#191970",
  mintcream: "#F5FFFA",
  mistyrose: "#FFE4E1",
  moccasin: "#FFE4B5",
  navajowhite: "#FFDEAD",
  navy: "#000080",
  oldlace: "#FDF5E6",
  olive: "#808000",
  olivedrab: "#6B8E23",
  orange: "#FFA500",
  orangered: "#FF4500",
  orchid: "#DA70D6",
  palegoldenrod: "#EEE8AA",
  palegreen: "#98FB98",
  paleturquoise: "#AFEEEE",
  palevioletred: "#DB7093",
  papayawhip: "#FFEFD5",
  peachpuff: "#FFDAB9",
  peru: "#CD853F",
  pink: "#FFC0CB",
  plum: "#DDA0DD",
  powderblue: "#B0E0E6",
  purple: "#800080",
  rebeccapurple: "#663399",
  red: "#FF0000",
  rosybrown: "#BC8F8F",
  royalblue: "#4169E1",
  saddlebrown: "#8B4513",
  salmon: "#FA8072",
  sandybrown: "#F4A460",
  seagreen: "#2E8B57",
  seashell: "#FFF5EE",
  sienna: "#A0522D",
  silver: "#C0C0C0",
  skyblue: "#87CEEB",
  slateblue: "#6A5ACD",
  slategray: "#708090",
  slategrey: "#708090",
  snow: "#FFFAFA",
  springgreen: "#00FF7F",
  steelblue: "#4682B4",
  tan: "#D2B48C",
  teal: "#008080",
  thistle: "#D8BFD8",
  tomato: "#FF6347",
  transparent: "#00000000",
  turquoise: "#40E0D0",
  violet: "#EE82EE",
  wheat: "#F5DEB3",
  white: "#FFFFFF",
  whitesmoke: "#F5F5F5",
  yellow: "#FFFF00",
  yellowgreen: "#9ACD32"
});
var Color = _Color;
function Validate(predicate, options = {}) {
  const { optional = false } = options;
  return addTransformToInstanceProperty(
    (target, property, value) => {
      var _a;
      const context = __spreadProps(__spreadValues({}, options), { target, property });
      if (optional && typeof value === "undefined" || predicate(value, context)) {
        if (isProperties(target[property]) && !isProperties(value)) {
          target[property].set(value);
          return target[property];
        }
        return value;
      }
      const cleanKey = String(property).replace(/^_*/, "");
      const targetName = (_a = target.constructor.className) != null ? _a : target.constructor.name.replace(/Properties$/, "");
      Logger.warn(
        `Property [${cleanKey}] of [${targetName}] cannot be set to [${stringify(value)}]${predicate.message ? `; expecting ${getPredicateMessage(predicate, context)}` : ""}, ignoring.`
      );
      return BREAK_TRANSFORM_CHAIN;
    },
    void 0,
    { optional }
  );
}
var AND = (...predicates) => {
  const messages = [];
  return predicateWithMessage(
    (value, ctx) => {
      messages.length = 0;
      return predicates.every((predicate) => {
        const isValid = predicate(value, ctx);
        if (!isValid) {
          messages.push(getPredicateMessage(predicate, ctx));
        }
        return isValid;
      });
    },
    () => messages.filter(Boolean).join(" AND ")
  );
};
var OR = (...predicates) => predicateWithMessage(
  (value, ctx) => predicates.some((predicate) => predicate(value, ctx)),
  (ctx) => predicates.map(getPredicateMessageMapper(ctx)).filter(Boolean).join(" OR ")
);
var OBJECT = attachObjectRestrictions(
  predicateWithMessage(
    (value, ctx) => isProperties(value) || isObject(value) && isProperties(ctx.target[ctx.property]),
    "an object"
  )
);
var BOOLEAN = predicateWithMessage(isBoolean, "a boolean");
var FUNCTION = predicateWithMessage(isFunction, "a function");
var STRING = predicateWithMessage(isString, "a string");
var NUMBER = attachNumberRestrictions(predicateWithMessage(isFiniteNumber, "a number"));
var NAN = predicateWithMessage((value) => isNumber(value) && isNaN(value), "NaN");
var POSITIVE_NUMBER = NUMBER.restrict({ min: 0 });
var RATIO = NUMBER.restrict({ min: 0, max: 1 });
var DEGREE = NUMBER.restrict({ min: -360, max: 360 });
var NUMBER_OR_NAN = OR(NUMBER, NAN);
var ARRAY = attachArrayRestrictions(predicateWithMessage(isArray, "an array"));
var ARRAY_OF = (predicate, message) => predicateWithMessage(
  (value, ctx) => isArray(value) && value.every((item) => predicate(item, ctx)),
  (ctx) => {
    var _a;
    const arrayMessage = (_a = getPredicateMessage(ARRAY, ctx)) != null ? _a : "";
    return message ? `${arrayMessage} of ${message}` : arrayMessage;
  }
);
var isComparable = (value) => isFiniteNumber(value) || isValidDate(value);
var LESS_THAN = (otherField) => predicateWithMessage(
  (v, ctx) => !isComparable(v) || !isComparable(ctx.target[otherField]) || v < ctx.target[otherField],
  `expected to be less than ${otherField}`
);
var GREATER_THAN = (otherField) => predicateWithMessage(
  (v, ctx) => !isComparable(v) || !isComparable(ctx.target[otherField]) || v > ctx.target[otherField],
  `expected to be greater than ${otherField}`
);
var DATE = predicateWithMessage(isValidDate, "Date object");
var DATE_OR_DATETIME_MS = OR(DATE, POSITIVE_NUMBER);
var colorMessage = `A color string can be in one of the following formats to be valid: #rgb, #rrggbb, rgb(r, g, b), rgba(r, g, b, a) or a CSS color name such as 'white', 'orange', 'cyan', etc`;
var COLOR_STRING = predicateWithMessage(
  (v) => isString(v) && Color.validColorString(v),
  `color String. ${colorMessage}`
);
var COLOR_STRING_ARRAY = predicateWithMessage(ARRAY_OF(COLOR_STRING), `color strings. ${colorMessage}`);
var BOOLEAN_ARRAY = ARRAY_OF(BOOLEAN, "boolean values");
var NUMBER_ARRAY = ARRAY_OF(NUMBER, "numbers");
var STRING_ARRAY = ARRAY_OF(STRING, "strings");
var DATE_ARRAY = predicateWithMessage(ARRAY_OF(DATE), "Date objects");
var OBJECT_ARRAY = predicateWithMessage(ARRAY_OF(OBJECT), "objects");
var LINE_CAP = UNION(["butt", "round", "square"], "a line cap");
var LINE_JOIN = UNION(["round", "bevel", "miter"], "a line join");
var LINE_DASH = predicateWithMessage(
  ARRAY_OF(POSITIVE_NUMBER),
  "numbers specifying the length in pixels of alternating dashes and gaps, for example, [6, 3] means dashes with a length of 6 pixels with gaps between of 3 pixels."
);
var POSITION = UNION(["top", "right", "bottom", "left"], "a position");
var FONT_STYLE = UNION(["normal", "italic", "oblique"], "a font style");
var FONT_WEIGHT = OR(
  UNION(["normal", "bold", "bolder", "lighter"], "a font weight"),
  NUMBER.restrict({ min: 1, max: 1e3 })
);
var TEXT_WRAP = UNION(["never", "always", "hyphenate", "on-space"], "a text wrap strategy");
var TEXT_ALIGN = UNION(["left", "center", "right"], "a text align");
var VERTICAL_ALIGN = UNION(["top", "middle", "bottom"], "a vertical align");
var OVERFLOW_STRATEGY = UNION(["ellipsis", "hide"], "an overflow strategy");
var DIRECTION = UNION(["horizontal", "vertical"], "a direction");
var PLACEMENT = UNION(["inside", "outside"], "a placement");
var INTERACTION_RANGE = OR(UNION(["exact", "nearest"], "interaction range"), NUMBER);
function UNION(options, message = "a") {
  return predicateWithMessage(
    (v) => options.includes(v),
    `${message} keyword such as ${joinUnionOptions(options)}`
  );
}
var MIN_SPACING = OR(AND(NUMBER.restrict({ min: 1 }), LESS_THAN("maxSpacing")), NAN);
var MAX_SPACING = OR(AND(NUMBER.restrict({ min: 1 }), GREATER_THAN("minSpacing")), NAN);
function predicateWithMessage(predicate, message) {
  predicate.message = message;
  return predicate;
}
function joinUnionOptions(options) {
  const values = options.map((option) => `'${option}'`);
  if (values.length === 1) {
    return values[0];
  }
  const lastValue = values.pop();
  return `${values.join(", ")} or ${lastValue}`;
}
function getPredicateMessage(predicate, ctx) {
  return isFunction(predicate.message) ? predicate.message(ctx) : predicate.message;
}
function getPredicateMessageMapper(ctx) {
  return (predicate) => getPredicateMessage(predicate, ctx);
}
function attachArrayRestrictions(predicate) {
  return Object.assign(predicate, {
    restrict({ length, minLength } = {}) {
      return predicateWithMessage(
        (value) => isArray(value) && (isNumber(length) ? value.length === length : true) && (isNumber(minLength) ? value.length >= minLength : true),
        isNumber(minLength) && minLength > 0 ? "a non-empty array" : isNumber(length) ? `an array of length ${length}` : "an array"
      );
    }
  });
}
function attachNumberRestrictions(predicate) {
  return Object.assign(predicate, {
    restrict({ min, max } = {}) {
      const message = ["a number"];
      const hasMin = isNumber(min);
      const hasMax = isNumber(max);
      if (hasMin && hasMax) {
        message.push(`between ${min} and ${max} inclusive`);
      } else if (hasMin) {
        message.push(`greater than or equal to ${min}`);
      } else if (hasMax) {
        message.push(`less than or equal to ${max}`);
      }
      return predicateWithMessage(
        (value) => isFiniteNumber(value) && (hasMin ? value >= min : true) && (hasMax ? value <= max : true),
        message.join(" ")
      );
    }
  });
}
function attachObjectRestrictions(predicate) {
  return Object.assign(predicate, {
    restrict(objectType) {
      const isInstanceOf = (value) => isProperties(value) && value instanceof objectType;
      return predicateWithMessage(
        (value, ctx) => isInstanceOf(value) || isObject(value) && isInstanceOf(ctx.target[ctx.property]),
        (ctx) => {
          var _a;
          return (_a = getPredicateMessage(predicate, ctx)) != null ? _a : "an object";
        }
      );
    }
  });
}
function stringify(value) {
  if (typeof value === "number") {
    if (isNaN(value))
      return "NaN";
    if (value === Infinity)
      return "Infinity";
    if (value === -Infinity)
      return "-Infinity";
  }
  return JSON.stringify(value);
}
var ChartAxisDirection = /* @__PURE__ */ ((ChartAxisDirection2) => {
  ChartAxisDirection2["X"] = "x";
  ChartAxisDirection2["Y"] = "y";
  return ChartAxisDirection2;
})(ChartAxisDirection || {});
var ID_MAP = {};
function resetIds() {
  for (const key in ID_MAP) {
    delete ID_MAP[key];
  }
}
function createId(instance) {
  var _a;
  const constructor = instance.constructor;
  const className = Object.hasOwn(constructor, "className") ? constructor.className : constructor.name;
  if (!className) {
    throw new Error(`The ${constructor} is missing the 'className' property.`);
  }
  const nextId = ((_a = ID_MAP[className]) != null ? _a : 0) + 1;
  ID_MAP[className] = nextId;
  return className + "-" + nextId;
}
function nearestSquared(point, objects, maxDistanceSquared = Infinity) {
  const result = { nearest: void 0, distanceSquared: maxDistanceSquared };
  for (const obj of objects) {
    const thisDistance = obj.distanceSquared(point);
    if (thisDistance === 0) {
      return { nearest: obj, distanceSquared: 0 };
    } else if (thisDistance < result.distanceSquared) {
      result.nearest = obj;
      result.distanceSquared = thisDistance;
    }
  }
  return result;
}
function nearestSquaredInContainer(point, container, maxDistanceSquared = Infinity) {
  const tpoint = container.transformPoint(point.x, point.y);
  const result = { nearest: void 0, distanceSquared: maxDistanceSquared };
  for (const child of container.children) {
    const { nearest, distanceSquared } = child.nearestSquared(tpoint, result.distanceSquared);
    if (distanceSquared === 0) {
      return { nearest, distanceSquared };
    } else if (distanceSquared < result.distanceSquared) {
      result.nearest = nearest;
      result.distanceSquared = distanceSquared;
    }
  }
  return result;
}
var _BBox = class _BBox2 {
  constructor(x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
  }
  clone() {
    const { x, y, width, height } = this;
    return new _BBox2(x, y, width, height);
  }
  equals(other) {
    return this.x === other.x && this.y === other.y && this.width === other.width && this.height === other.height;
  }
  containsPoint(x, y) {
    return x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height;
  }
  collidesBBox(other) {
    return this.x < other.x + other.width && this.x + this.width > other.x && this.y < other.y + other.height && this.y + this.height > other.y;
  }
  isInfinite() {
    return Math.abs(this.x) === Infinity || Math.abs(this.y) === Infinity || Math.abs(this.width) === Infinity || Math.abs(this.height) === Infinity;
  }
  distanceSquared(point) {
    if (this.containsPoint(point.x, point.y)) {
      return 0;
    }
    const dx = point.x - Math.max(this.x, Math.min(point.x, this.x + this.width));
    const dy = point.y - Math.max(this.y, Math.min(point.y, this.y + this.height));
    return dx * dx + dy * dy;
  }
  static nearestBox(point, boxes) {
    return nearestSquared(point, boxes);
  }
  shrink(amount, position) {
    const apply = (pos, amt) => {
      switch (pos) {
        case "top":
          this.y += amt;
        case "bottom":
          this.height -= amt;
          break;
        case "left":
          this.x += amt;
        case "right":
          this.width -= amt;
          break;
        case "vertical":
          this.y += amt;
          this.height -= amt * 2;
          break;
        case "horizontal":
          this.x += amt;
          this.width -= amt * 2;
          break;
        case void 0:
          this.x += amt;
          this.width -= amt * 2;
          this.y += amt;
          this.height -= amt * 2;
          break;
        default:
      }
    };
    if (typeof amount === "number") {
      apply(position, amount);
    } else if (typeof amount === "object") {
      Object.entries(amount).forEach(([pos, amt]) => apply(pos, amt));
    }
    return this;
  }
  grow(amount, position) {
    if (typeof amount === "number") {
      this.shrink(-amount, position);
    } else {
      const paddingCopy = __spreadValues({}, amount);
      for (const key in paddingCopy) {
        paddingCopy[key] *= -1;
      }
      this.shrink(paddingCopy);
    }
    return this;
  }
  static merge(boxes) {
    let left = Infinity;
    let top = Infinity;
    let right = -Infinity;
    let bottom = -Infinity;
    boxes.forEach((box) => {
      if (box.x < left) {
        left = box.x;
      }
      if (box.y < top) {
        top = box.y;
      }
      if (box.x + box.width > right) {
        right = box.x + box.width;
      }
      if (box.y + box.height > bottom) {
        bottom = box.y + box.height;
      }
    });
    return new _BBox2(left, top, right - left, bottom - top);
  }
};
_BBox.zero = new _BBox(0, 0, 0, 0);
var BBox = _BBox;
var _Matrix = class _Matrix2 {
  get e() {
    return [...this.elements];
  }
  constructor(elements = [1, 0, 0, 1, 0, 0]) {
    this.elements = elements;
  }
  setElements(elements) {
    const e = this.elements;
    e[0] = elements[0];
    e[1] = elements[1];
    e[2] = elements[2];
    e[3] = elements[3];
    e[4] = elements[4];
    e[5] = elements[5];
    return this;
  }
  get identity() {
    const e = this.elements;
    return e[0] === 1 && e[1] === 0 && e[2] === 0 && e[3] === 1 && e[4] === 0 && e[5] === 0;
  }
  /**
   * Performs the AxB matrix multiplication and saves the result
   * to `C`, if given, or to `A` otherwise.
   */
  AxB(A, B, C) {
    const a = A[0] * B[0] + A[2] * B[1], b = A[1] * B[0] + A[3] * B[1], c = A[0] * B[2] + A[2] * B[3], d = A[1] * B[2] + A[3] * B[3], e = A[0] * B[4] + A[2] * B[5] + A[4], f = A[1] * B[4] + A[3] * B[5] + A[5];
    C = C != null ? C : A;
    C[0] = a;
    C[1] = b;
    C[2] = c;
    C[3] = d;
    C[4] = e;
    C[5] = f;
  }
  /**
   * The `other` matrix gets post-multiplied to the current matrix.
   * Returns the current matrix.
   * @param other
   */
  multiplySelf(other) {
    this.AxB(this.elements, other.elements);
    return this;
  }
  /**
   * The `other` matrix gets post-multiplied to the current matrix.
   * Returns a new matrix.
   * @param other
   */
  multiply(other) {
    const elements = new Array(6);
    this.AxB(this.elements, other.elements, elements);
    return new _Matrix2(elements);
  }
  preMultiplySelf(other) {
    this.AxB(other.elements, this.elements, this.elements);
    return this;
  }
  /**
   * Returns the inverse of this matrix as a new matrix.
   */
  inverse() {
    const el = this.elements;
    let a = el[0], b = el[1], c = el[2], d = el[3];
    const e = el[4], f = el[5];
    const rD = 1 / (a * d - b * c);
    a *= rD;
    b *= rD;
    c *= rD;
    d *= rD;
    return new _Matrix2([d, -b, -c, a, c * f - d * e, b * e - a * f]);
  }
  /**
   * Save the inverse of this matrix to the given matrix.
   */
  inverseTo(other) {
    const el = this.elements;
    let a = el[0], b = el[1], c = el[2], d = el[3];
    const e = el[4], f = el[5];
    const rD = 1 / (a * d - b * c);
    a *= rD;
    b *= rD;
    c *= rD;
    d *= rD;
    other.setElements([d, -b, -c, a, c * f - d * e, b * e - a * f]);
    return this;
  }
  invertSelf() {
    const el = this.elements;
    let a = el[0], b = el[1], c = el[2], d = el[3];
    const e = el[4], f = el[5];
    const rD = 1 / (a * d - b * c);
    a *= rD;
    b *= rD;
    c *= rD;
    d *= rD;
    el[0] = d;
    el[1] = -b;
    el[2] = -c;
    el[3] = a;
    el[4] = c * f - d * e;
    el[5] = b * e - a * f;
    return this;
  }
  transformPoint(x, y) {
    const e = this.elements;
    return {
      x: x * e[0] + y * e[2] + e[4],
      y: x * e[1] + y * e[3] + e[5]
    };
  }
  transformBBox(bbox, target) {
    const elements = this.elements;
    const xx = elements[0];
    const xy = elements[1];
    const yx = elements[2];
    const yy = elements[3];
    const h_w = bbox.width * 0.5;
    const h_h = bbox.height * 0.5;
    const cx = bbox.x + h_w;
    const cy = bbox.y + h_h;
    const w = Math.abs(h_w * xx) + Math.abs(h_h * yx);
    const h = Math.abs(h_w * xy) + Math.abs(h_h * yy);
    if (!target) {
      target = new BBox(0, 0, 0, 0);
    }
    target.x = cx * xx + cy * yx + elements[4] - w;
    target.y = cx * xy + cy * yy + elements[5] - h;
    target.width = w + w;
    target.height = h + h;
    return target;
  }
  toContext(ctx) {
    if (this.identity) {
      return;
    }
    const e = this.elements;
    ctx.transform(e[0], e[1], e[2], e[3], e[4], e[5]);
  }
  static flyweight(sourceMatrix) {
    return _Matrix2.instance.setElements(sourceMatrix.elements);
  }
  static updateTransformMatrix(matrix, scalingX, scalingY, rotation, translationX, translationY, opts) {
    const [bbcx, bbcy] = [0, 0];
    const sx = scalingX;
    const sy = scalingY;
    let scx;
    let scy;
    if (sx === 1 && sy === 1) {
      scx = 0;
      scy = 0;
    } else {
      scx = (opts == null ? void 0 : opts.scalingCenterX) == null ? bbcx : opts == null ? void 0 : opts.scalingCenterX;
      scy = (opts == null ? void 0 : opts.scalingCenterY) == null ? bbcy : opts == null ? void 0 : opts.scalingCenterY;
    }
    const r = rotation;
    const cos = Math.cos(r);
    const sin = Math.sin(r);
    let rcx;
    let rcy;
    if (r === 0) {
      rcx = 0;
      rcy = 0;
    } else {
      rcx = (opts == null ? void 0 : opts.rotationCenterX) == null ? bbcx : opts == null ? void 0 : opts.rotationCenterX;
      rcy = (opts == null ? void 0 : opts.rotationCenterY) == null ? bbcy : opts == null ? void 0 : opts.rotationCenterY;
    }
    const tx = translationX;
    const ty = translationY;
    const tx4 = scx * (1 - sx) - rcx;
    const ty4 = scy * (1 - sy) - rcy;
    matrix.setElements([
      cos * sx,
      sin * sx,
      -sin * sy,
      cos * sy,
      cos * tx4 - sin * ty4 + rcx + tx,
      sin * tx4 + cos * ty4 + rcy + ty
    ]);
    return matrix;
  }
  static fromContext(ctx) {
    const domMatrix = ctx.getTransform();
    return new _Matrix2([domMatrix.a, domMatrix.b, domMatrix.c, domMatrix.d, domMatrix.e, domMatrix.f]);
  }
};
_Matrix.instance = new _Matrix();
var Matrix = _Matrix;
var PointerEvents = /* @__PURE__ */ ((PointerEvents2) => {
  PointerEvents2[PointerEvents2["All"] = 0] = "All";
  PointerEvents2[PointerEvents2["None"] = 1] = "None";
  return PointerEvents2;
})(PointerEvents || {});
var zIndexChangedCallback = (o) => {
  if (o.parent) {
    o.parent.dirtyZIndex = true;
  }
  o.zIndexChanged();
};
var _Node = class _Node2 extends ChangeDetectable {
  constructor({ isVirtual, tag } = {}) {
    super();
    this.serialNumber = _Node2._nextSerialNumber++;
    this.id = createId(this);
    this.isContainerNode = false;
    this._virtualChildren = [];
    this._children = [];
    this.childSet = {};
    this.matrix = new Matrix();
    this.inverseMatrix = new Matrix();
    this.dirtyTransform = false;
    this.scalingX = 1;
    this.scalingY = 1;
    this.scalingCenterX = null;
    this.scalingCenterY = null;
    this.rotationCenterX = null;
    this.rotationCenterY = null;
    this.rotation = 0;
    this.translationX = 0;
    this.translationY = 0;
    this.visible = true;
    this.dirtyZIndex = false;
    this.zIndex = 0;
    this.zIndexSubOrder = void 0;
    this.pointerEvents = 0;
    this.isVirtual = isVirtual != null ? isVirtual : false;
    this.tag = tag != null ? tag : NaN;
  }
  /**
   * Some arbitrary data bound to the node.
   */
  get datum() {
    var _a, _b;
    return (_b = this._datum) != null ? _b : (_a = this._parent) == null ? void 0 : _a.datum;
  }
  get previousDatum() {
    return this._previousDatum;
  }
  set datum(datum) {
    if (this._datum !== datum)
      this._previousDatum = this._datum;
    this._datum = datum;
  }
  _setLayerManager(value) {
    this._layerManager = value;
    this._debug = value == null ? void 0 : value.debug;
    for (const child of this._children) {
      child._setLayerManager(value);
    }
    for (const child of this._virtualChildren) {
      child._setLayerManager(value);
    }
  }
  get layerManager() {
    return this._layerManager;
  }
  get parent() {
    return this._parent;
  }
  get children() {
    if (this._virtualChildren.length === 0)
      return this._children;
    const result = [...this._children];
    for (const next of this._virtualChildren) {
      result.push(...next.children);
    }
    return result;
  }
  get virtualChildren() {
    return this._virtualChildren;
  }
  hasVirtualChildren() {
    return this._virtualChildren.length > 0;
  }
  // new Set<Node>()
  setProperties(styles, pickKeys) {
    const keys = pickKeys != null ? pickKeys : Object.keys(styles);
    for (const key of keys) {
      this[key] = styles[key];
    }
    return this;
  }
  /**
   * Appends one or more new node instances to this parent.
   * If one needs to:
   * - move a child to the end of the list of children
   * - move a child from one parent to another (including parents in other scenes)
   * one should use the {@link insertBefore} method instead.
   * @param nodes A node or nodes to append.
   */
  append(nodes) {
    if (!Array.isArray(nodes)) {
      nodes = [nodes];
    }
    for (const node of nodes) {
      if (node.parent) {
        throw new Error(`${node} already belongs to another parent: ${node.parent}.`);
      }
      if (node.layerManager) {
        throw new Error(`${node} already belongs to a scene: ${node.layerManager}.`);
      }
      if (this.childSet[node.id]) {
        throw new Error(`Duplicate ${node.constructor.name} node: ${node}`);
      }
      if (node.isVirtual) {
        this._virtualChildren.push(node);
      } else {
        this._children.push(node);
      }
      this.childSet[node.id] = true;
      node._parent = this;
      node._setLayerManager(this.layerManager);
    }
    this.dirtyZIndex = true;
    this.markDirty(
      this,
      3
      /* MAJOR */
    );
  }
  appendChild(node) {
    this.append(node);
    return node;
  }
  removeChild(node) {
    const error = () => {
      throw new Error(`The node to be removed is not a child of this node.`);
    };
    if (node.parent !== this) {
      error();
    }
    if (node.isVirtual) {
      const i = this._virtualChildren.indexOf(node);
      if (i < 0)
        error();
      this._virtualChildren.splice(i, 1);
    } else {
      const i = this._children.indexOf(node);
      if (i < 0)
        error();
      this._children.splice(i, 1);
    }
    delete this.childSet[node.id];
    node._parent = void 0;
    node._setLayerManager();
    this.dirtyZIndex = true;
    this.markDirty(
      node,
      3
      /* MAJOR */
    );
    return node;
  }
  calculateCumulativeMatrix() {
    this.computeTransformMatrix();
    const matrix = Matrix.flyweight(this.matrix);
    let parent = this.parent;
    while (parent) {
      parent.computeTransformMatrix();
      matrix.preMultiplySelf(parent.matrix);
      parent = parent.parent;
    }
    return matrix;
  }
  transformPoint(x, y) {
    const matrix = this.calculateCumulativeMatrix();
    return matrix.invertSelf().transformPoint(x, y);
  }
  inverseTransformPoint(x, y) {
    const matrix = this.calculateCumulativeMatrix();
    return matrix.transformPoint(x, y);
  }
  transformBBox(bbox) {
    const matrix = this.calculateCumulativeMatrix();
    return matrix.invertSelf().transformBBox(bbox);
  }
  inverseTransformBBox(bbox) {
    const matrix = this.calculateCumulativeMatrix();
    return matrix.transformBBox(bbox);
  }
  markDirtyTransform() {
    this.dirtyTransform = true;
    this.markDirty(
      this,
      3
      /* MAJOR */
    );
  }
  containsPoint(_x, _y) {
    return false;
  }
  /**
   * Hit testing method.
   * Recursively checks if the given point is inside this node or any of its children.
   * Returns the first matching node or `undefined`.
   * Nodes that render later (show on top) are hit tested first.
   */
  pickNode(x, y) {
    var _a;
    if (!this.visible || this.pointerEvents === 1 || !this.containsPoint(x, y)) {
      return;
    }
    const children = this.children;
    if (children.length > 1e3) {
      for (let i = children.length - 1; i >= 0; i--) {
        const child = children[i];
        const containsPoint = (_a = child.computeTransformedBBox()) == null ? void 0 : _a.containsPoint(x, y);
        const hit = containsPoint ? child.pickNode(x, y) : void 0;
        if (hit) {
          return hit;
        }
      }
    } else if (children.length) {
      for (let i = children.length - 1; i >= 0; i--) {
        const hit = children[i].pickNode(x, y);
        if (hit) {
          return hit;
        }
      }
    } else if (!this.isContainerNode) {
      return this;
    }
  }
  findNodes(predicate) {
    const result = predicate(this) ? [this] : [];
    for (const child of this.children) {
      const childResult = child.findNodes(predicate);
      if (childResult) {
        result.push(...childResult);
      }
    }
    return result;
  }
  computeBBox() {
    return;
  }
  computeTransformedBBox() {
    const bbox = this.computeBBox();
    if (!bbox) {
      return void 0;
    }
    this.computeTransformMatrix();
    const matrix = Matrix.flyweight(this.matrix);
    let parent = this.parent;
    while (parent) {
      parent.computeTransformMatrix();
      matrix.preMultiplySelf(parent.matrix);
      parent = parent.parent;
    }
    matrix.transformBBox(bbox, bbox);
    return bbox;
  }
  computeTransformMatrix() {
    if (!this.dirtyTransform) {
      return;
    }
    const {
      matrix,
      scalingX,
      scalingY,
      rotation,
      translationX,
      translationY,
      scalingCenterX,
      scalingCenterY,
      rotationCenterX,
      rotationCenterY
    } = this;
    Matrix.updateTransformMatrix(matrix, scalingX, scalingY, rotation, translationX, translationY, {
      scalingCenterX,
      scalingCenterY,
      rotationCenterX,
      rotationCenterY
    });
    matrix.inverseTo(this.inverseMatrix);
    this.dirtyTransform = false;
  }
  render(renderCtx) {
    const { stats } = renderCtx;
    this._dirty = 0;
    if (stats)
      stats.nodesRendered++;
  }
  clearBBox(ctx) {
    const bbox = this.computeBBox();
    if (bbox == null) {
      return;
    }
    const { x, y, width, height } = bbox;
    const topLeft = this.transformPoint(x, y);
    const bottomRight = this.transformPoint(x + width, y + height);
    ctx.clearRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
  }
  markDirty(_source, type = 1, parentType = type) {
    if (this._dirty > type) {
      return;
    }
    if (this._dirty === type && type === parentType) {
      return;
    }
    this._dirty = type;
    if (this.parent) {
      this.parent.markDirty(this, parentType);
    } else if (this.layerManager) {
      this.layerManager.markDirty();
    }
  }
  get dirty() {
    return this._dirty;
  }
  markClean(opts) {
    const { force = false, recursive = true } = opts != null ? opts : {};
    if (this._dirty === 0 && !force) {
      return;
    }
    this._dirty = 0;
    if (recursive !== false) {
      for (const child of this._virtualChildren) {
        child.markClean({ force });
      }
    }
    if (recursive === true) {
      for (const child of this._children) {
        child.markClean({ force });
      }
    }
  }
  visibilityChanged() {
  }
  get nodeCount() {
    let count2 = 1;
    let dirtyCount = this._dirty >= 0 || this.dirtyTransform ? 1 : 0;
    let visibleCount = this.visible ? 1 : 0;
    const countChild = (child) => {
      const { count: childCount, visibleCount: childVisibleCount, dirtyCount: childDirtyCount } = child.nodeCount;
      count2 += childCount;
      visibleCount += childVisibleCount;
      dirtyCount += childDirtyCount;
    };
    for (const child of this._children) {
      countChild(child);
    }
    for (const child of this._virtualChildren) {
      countChild(child);
    }
    return { count: count2, visibleCount, dirtyCount };
  }
  zIndexChanged() {
  }
};
_Node._nextSerialNumber = 0;
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "scalingX", 2);
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "scalingY", 2);
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "scalingCenterX", 2);
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "scalingCenterY", 2);
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "rotationCenterX", 2);
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "rotationCenterY", 2);
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "rotation", 2);
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "translationX", 2);
__decorateClass([
  SceneChangeDetection({ type: "transform" })
], _Node.prototype, "translationY", 2);
__decorateClass([
  SceneChangeDetection({ redraw: 3, changeCb: (o) => o.visibilityChanged() })
], _Node.prototype, "visible", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 1,
    changeCb: zIndexChangedCallback
  })
], _Node.prototype, "zIndex", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 1,
    changeCb: zIndexChangedCallback
  })
], _Node.prototype, "zIndexSubOrder", 2);
var Node = _Node;
function hasConstrainedCanvasMemory() {
  if (typeof navigator === "undefined")
    return false;
  const iPhoneOSMatch = navigator.userAgent.match(/\(iPhone; CPU iPhone OS (\d+_\d+_\d+) like Mac OS X\)/);
  if (iPhoneOSMatch == null)
    return false;
  const versionString = iPhoneOSMatch[1].split("_");
  const major = Number(versionString[0]);
  if (major > 16) {
    return false;
  } else if (major === 16) {
    const minor = Number(versionString[1]);
    return minor < 6;
  }
  return true;
}
var _HdpiCanvas = class _HdpiCanvas2 {
  // The width/height attributes of the Canvas element default to
  // 300/150 according to w3.org.
  constructor(opts) {
    this._enabled = true;
    this._pixelRatio = NaN;
    this._width = 0;
    this._height = 0;
    const {
      document: document2,
      window: window2,
      width = 600,
      height = 300,
      domLayer = false,
      zIndex = 0,
      name = void 0,
      overrideDevicePixelRatio = void 0
    } = opts;
    this.document = document2;
    this.window = window2;
    _HdpiCanvas2.document = document2;
    this.element = document2.createElement("canvas");
    this.element.width = width;
    this.element.height = height;
    this.realContext = this.element.getContext("2d");
    this.imageSource = this.realContext.canvas;
    const { style } = this.element;
    style.userSelect = "none";
    style.display = "block";
    if (domLayer) {
      style.position = "absolute";
      style.zIndex = String(zIndex);
      style.top = "0";
      style.left = "0";
      style.pointerEvents = "none";
      style.opacity = `1`;
      if (name) {
        this.element.id = name;
      }
    }
    this.context = this.setPixelRatio(overrideDevicePixelRatio);
    this.resize(width, height);
  }
  set container(value) {
    if (this._container !== value) {
      this.remove();
      if (value) {
        value.appendChild(this.element);
      }
      this._container = value;
    }
  }
  get container() {
    return this._container;
  }
  set enabled(value) {
    this.element.style.display = value ? "block" : "none";
    this._enabled = !!value;
  }
  get enabled() {
    return this._enabled;
  }
  remove() {
    const { parentNode } = this.element;
    if (parentNode != null) {
      parentNode.removeChild(this.element);
    }
  }
  destroy() {
    this.element.remove();
    this.element.width = 0;
    this.element.height = 0;
    this.context.clearRect(0, 0, 0, 0);
    Object.freeze(this);
  }
  snapshot() {
  }
  clear() {
    this.context.save();
    this.context.resetTransform();
    this.context.clearRect(0, 0, this.width, this.height);
    this.context.restore();
  }
  toImage() {
    const img = this.document.createElement("img");
    img.src = this.getDataURL();
    return img;
  }
  getDataURL(type) {
    return this.element.toDataURL(type);
  }
  /**
   * @param fileName The name of the downloaded file.
   * @param fileFormat The file format, the default is `image/png`
   */
  download(fileName, fileFormat = "image/png") {
    fileName = (fileName != null ? fileName : "").trim() || "image";
    const dataUrl = this.getDataURL(fileFormat);
    const document2 = this.document;
    const a = document2.createElement("a");
    a.href = dataUrl;
    a.download = fileName;
    a.style.display = "none";
    document2.body.appendChild(a);
    a.click();
    document2.body.removeChild(a);
  }
  get pixelRatio() {
    return this._pixelRatio;
  }
  /**
   * Changes the pixel ratio of the Canvas element to the given value,
   * or uses the window.devicePixelRatio (default), then resizes the Canvas
   * element accordingly (default).
   */
  setPixelRatio(ratio) {
    let pixelRatio = ratio != null ? ratio : this.window.devicePixelRatio;
    if (hasConstrainedCanvasMemory()) {
      pixelRatio = 1;
    }
    this._pixelRatio = pixelRatio;
    return _HdpiCanvas2.overrideScale(this.realContext, pixelRatio);
  }
  set pixelated(value) {
    this.element.style.imageRendering = value ? "pixelated" : "auto";
  }
  get pixelated() {
    return this.element.style.imageRendering === "pixelated";
  }
  get width() {
    return this._width;
  }
  get height() {
    return this._height;
  }
  resize(width, height) {
    if (!(width > 0 && height > 0)) {
      return;
    }
    const { element: element2, context, pixelRatio } = this;
    element2.width = Math.round(width * pixelRatio);
    element2.height = Math.round(height * pixelRatio);
    element2.style.width = width + "px";
    element2.style.height = height + "px";
    context.resetTransform();
    this._width = width;
    this._height = height;
  }
  static get textMeasuringContext() {
    if (this._textMeasuringContext) {
      return this._textMeasuringContext;
    }
    const canvas = this.document.createElement("canvas");
    this._textMeasuringContext = canvas.getContext("2d");
    return this._textMeasuringContext;
  }
  static get svgText() {
    if (this._svgText) {
      return this._svgText;
    }
    const xmlns = "http://www.w3.org/2000/svg";
    const svg = document.createElementNS(xmlns, "svg");
    svg.setAttribute("width", "100");
    svg.setAttribute("height", "100");
    if (svg.classList) {
      svg.classList.add("text-measuring-svg");
    } else {
      svg.setAttribute("class", "text-measuring-svg");
    }
    svg.style.position = "absolute";
    svg.style.top = "-1000px";
    svg.style.visibility = "hidden";
    const svgText = document.createElementNS(xmlns, "text");
    svgText.setAttribute("x", "0");
    svgText.setAttribute("y", "30");
    svgText.setAttribute("text", "black");
    svg.appendChild(svgText);
    document.body.appendChild(svg);
    this._svgText = svgText;
    return svgText;
  }
  static get has() {
    if (this._has) {
      return this._has;
    }
    const isChrome = typeof navigator === "undefined" || navigator.userAgent.indexOf("Chrome") > -1;
    const isFirefox = typeof navigator !== "undefined" && navigator.userAgent.indexOf("Firefox") > -1;
    const isSafari = !isChrome && typeof navigator !== "undefined" && navigator.userAgent.indexOf("Safari") > -1;
    this._has = Object.freeze({
      textMetrics: this.textMeasuringContext.measureText("test").actualBoundingBoxDescent !== void 0 && // Firefox implemented advanced TextMetrics object in v74:
      // https://bugzilla.mozilla.org/show_bug.cgi?id=1102584
      // but it's buggy, so we'll keep using the SVG for text measurement in Firefox for now.
      !isFirefox && !isSafari,
      getTransform: this.textMeasuringContext.getTransform !== void 0
    });
    return this._has;
  }
  static measureText(text, font, textBaseline, textAlign) {
    const ctx = this.textMeasuringContext;
    ctx.font = font;
    ctx.textBaseline = textBaseline;
    ctx.textAlign = textAlign;
    return ctx.measureText(text);
  }
  /**
   * Returns the width and height of the measured text.
   * @param text The single-line text to measure.
   * @param font The font shorthand string.
   */
  static getTextSize(text, font) {
    if (this.has.textMetrics) {
      const ctx = this.textMeasuringContext;
      ctx.font = font;
      const metrics = ctx.measureText(text);
      return {
        width: metrics.width,
        height: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent
      };
    } else {
      return this.measureSvgText(text, font);
    }
  }
  static measureSvgText(text, font) {
    const cache = this.textSizeCache;
    const fontCache = cache[font];
    if (fontCache) {
      const size2 = fontCache[text];
      if (size2) {
        return size2;
      }
    } else {
      cache[font] = {};
    }
    const svgText = this.svgText;
    svgText.style.font = font;
    svgText.textContent = text;
    const bbox = svgText.getBBox();
    const size = {
      width: bbox.width,
      height: bbox.height
    };
    cache[font][text] = size;
    return size;
  }
  static overrideScale(ctx, scale2) {
    let depth = 0;
    const overrides = {
      save() {
        this.$save();
        depth++;
      },
      restore() {
        if (depth > 0) {
          this.$restore();
          depth--;
        } else {
          throw new Error("AG Charts - Unable to restore() past depth 0");
        }
      },
      setTransform(a, b, c, d, e, f) {
        if (typeof a === "object") {
          this.$setTransform(a);
        } else {
          this.$setTransform(a * scale2, b * scale2, c * scale2, d * scale2, e * scale2, f * scale2);
        }
      },
      resetTransform() {
        this.$setTransform(scale2, 0, 0, scale2, 0, 0);
      },
      verifyDepthZero() {
        if (depth !== 0) {
          throw new Error("AG Charts - Save/restore depth is non-zero: " + depth);
        }
      }
    };
    for (const name in overrides) {
      if (Object.hasOwn(overrides, name)) {
        if (!ctx["$" + name]) {
          ctx["$" + name] = ctx[name];
        }
        ctx[name] = overrides[name];
      }
    }
    return ctx;
  }
};
_HdpiCanvas.document = globalThis.document;
_HdpiCanvas.textSizeCache = {};
var HdpiCanvas = _HdpiCanvas;
var Gradient = class {
  constructor() {
    this.stops = [];
  }
};
var LinearGradient = class extends Gradient {
  constructor() {
    super(...arguments);
    this.angle = 0;
  }
  createGradient(ctx, bbox) {
    const angleOffset = 90;
    const { stops, angle } = this;
    const radians = normalizeAngle360(toRadians(angle + angleOffset));
    const cos = Math.cos(radians);
    const sin = Math.sin(radians);
    const w = bbox.width;
    const h = bbox.height;
    const cx = bbox.x + w * 0.5;
    const cy = bbox.y + h * 0.5;
    if (w > 0 && h > 0) {
      const diagonal = Math.sqrt(h * h + w * w) / 2;
      const diagonalAngle = Math.atan2(h, w);
      let quarteredAngle;
      if (radians < Math.PI / 2) {
        quarteredAngle = radians;
      } else if (radians < Math.PI) {
        quarteredAngle = Math.PI - radians;
      } else if (radians < 3 * Math.PI / 2) {
        quarteredAngle = radians - Math.PI;
      } else {
        quarteredAngle = 2 * Math.PI - radians;
      }
      const l = diagonal * Math.abs(Math.cos(quarteredAngle - diagonalAngle));
      const gradient = ctx.createLinearGradient(cx + cos * l, cy + sin * l, cx - cos * l, cy - sin * l);
      stops.forEach((stop) => {
        gradient.addColorStop(stop.offset, stop.color);
      });
      return gradient;
    }
    return "black";
  }
};
var LINEAR_GRADIENT_REGEXP = /^linear-gradient\((.*?)deg,\s*(.*?)\s*\)$/i;
var _Shape = class _Shape2 extends Node {
  constructor() {
    super(...arguments);
    this.fillOpacity = 1;
    this.strokeOpacity = 1;
    this.fill = _Shape2.defaultStyles.fill;
    this.stroke = _Shape2.defaultStyles.stroke;
    this.strokeWidth = _Shape2.defaultStyles.strokeWidth;
    this.lineDash = _Shape2.defaultStyles.lineDash;
    this.lineDashOffset = _Shape2.defaultStyles.lineDashOffset;
    this.lineCap = _Shape2.defaultStyles.lineCap;
    this.lineJoin = _Shape2.defaultStyles.lineJoin;
    this.opacity = _Shape2.defaultStyles.opacity;
    this.fillShadow = _Shape2.defaultStyles.fillShadow;
  }
  /**
   * Restores the default styles introduced by this subclass.
   */
  restoreOwnStyles() {
    const styles = this.constructor.defaultStyles;
    const keys = Object.getOwnPropertyNames(styles);
    for (let i = 0, n = keys.length; i < n; i++) {
      const key = keys[i];
      this[key] = styles[key];
    }
  }
  updateGradient() {
    const { fill } = this;
    let linearGradientMatch;
    if ((fill == null ? void 0 : fill.startsWith("linear-gradient")) && (linearGradientMatch = LINEAR_GRADIENT_REGEXP.exec(fill))) {
      const angle = parseFloat(linearGradientMatch[1]);
      const colors = [];
      const colorsPart = linearGradientMatch[2];
      const colorRegex = /(#[0-9a-f]+)|(rgba?\(.+?\))|([a-z]+)/gi;
      let c;
      while (c = colorRegex.exec(colorsPart)) {
        colors.push(c[0]);
      }
      this.gradient = new LinearGradient();
      this.gradient.angle = angle;
      this.gradient.stops = colors.map((color, index) => {
        const offset4 = index / (colors.length - 1);
        return { offset: offset4, color };
      });
    } else {
      this.gradient = void 0;
    }
  }
  /**
   * Returns a device-pixel aligned coordinate (or length if length is supplied).
   *
   * NOTE: Not suitable for strokes, since the stroke needs to be offset to the middle
   * of a device pixel.
   */
  align(start, length) {
    var _a, _b, _c;
    const pixelRatio = (_c = (_b = (_a = this.layerManager) == null ? void 0 : _a.canvas) == null ? void 0 : _b.pixelRatio) != null ? _c : 1;
    const alignedStart = Math.round(start * pixelRatio) / pixelRatio;
    if (length == void 0) {
      return alignedStart;
    }
    if (length === 0) {
      return 0;
    }
    if (length < 1) {
      return Math.ceil(length * pixelRatio) / pixelRatio;
    }
    return Math.round((length + start) * pixelRatio) / pixelRatio - alignedStart;
  }
  fillStroke(ctx) {
    this.renderFill(ctx);
    this.renderStroke(ctx);
  }
  renderFill(ctx) {
    if (this.fill) {
      const { globalAlpha } = ctx;
      this.applyFill(ctx);
      this.applyFillAlpha(ctx);
      this.applyShadow(ctx);
      ctx.fill();
      ctx.globalAlpha = globalAlpha;
    }
    ctx.shadowColor = "rgba(0, 0, 0, 0)";
  }
  applyFill(ctx) {
    if (this.gradient) {
      ctx.fillStyle = this.gradient.createGradient(ctx, this.computeBBox());
    } else {
      ctx.fillStyle = this.fill;
    }
  }
  applyFillAlpha(ctx) {
    const { globalAlpha } = ctx;
    ctx.globalAlpha = globalAlpha * this.opacity * this.fillOpacity;
  }
  applyShadow(ctx) {
    var _a, _b;
    const pixelRatio = (_b = (_a = this.layerManager) == null ? void 0 : _a.canvas.pixelRatio) != null ? _b : 1;
    const fillShadow = this.fillShadow;
    if (fillShadow == null ? void 0 : fillShadow.enabled) {
      ctx.shadowColor = fillShadow.color;
      ctx.shadowOffsetX = fillShadow.xOffset * pixelRatio;
      ctx.shadowOffsetY = fillShadow.yOffset * pixelRatio;
      ctx.shadowBlur = fillShadow.blur * pixelRatio;
    }
  }
  renderStroke(ctx) {
    if (this.stroke && this.strokeWidth) {
      const { globalAlpha } = ctx;
      ctx.strokeStyle = this.stroke;
      ctx.globalAlpha = globalAlpha * this.opacity * this.strokeOpacity;
      ctx.lineWidth = this.strokeWidth;
      if (this.lineDash) {
        ctx.setLineDash(this.lineDash);
      }
      if (this.lineDashOffset) {
        ctx.lineDashOffset = this.lineDashOffset;
      }
      if (this.lineCap) {
        ctx.lineCap = this.lineCap;
      }
      if (this.lineJoin) {
        ctx.lineJoin = this.lineJoin;
      }
      ctx.stroke();
      ctx.globalAlpha = globalAlpha;
    }
  }
  containsPoint(x, y) {
    return this.isPointInPath(x, y);
  }
};
_Shape.defaultStyles = Object.assign(
  {},
  {
    fill: "black",
    stroke: void 0,
    strokeWidth: 0,
    lineDash: void 0,
    lineDashOffset: 0,
    lineCap: void 0,
    lineJoin: void 0,
    opacity: 1,
    fillShadow: void 0
  }
);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], _Shape.prototype, "fillOpacity", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], _Shape.prototype, "strokeOpacity", 2);
__decorateClass([
  SceneChangeDetection({ redraw: 2, changeCb: (s) => s.updateGradient() })
], _Shape.prototype, "fill", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], _Shape.prototype, "stroke", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], _Shape.prototype, "strokeWidth", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], _Shape.prototype, "lineDash", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], _Shape.prototype, "lineDashOffset", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], _Shape.prototype, "lineCap", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], _Shape.prototype, "lineJoin", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2,
    convertor: (v) => Math.min(1, Math.max(0, v))
  })
], _Shape.prototype, "opacity", 2);
__decorateClass([
  SceneChangeDetection({ redraw: 2, checkDirtyOnAssignment: true })
], _Shape.prototype, "fillShadow", 2);
var Shape = _Shape;
var ellipsis = "\u2026";
function SceneFontChangeDetection(opts) {
  const { redraw = 3, changeCb } = opts != null ? opts : {};
  return SceneChangeDetection({ redraw, type: "font", changeCb });
}
var _Text = class _Text2 extends Shape {
  constructor() {
    super(...arguments);
    this.x = 0;
    this.y = 0;
    this.lines = [];
    this.text = void 0;
    this._dirtyFont = true;
    this.fontSize = 10;
    this.fontFamily = "sans-serif";
    this.textAlign = _Text2.defaultStyles.textAlign;
    this.textBaseline = _Text2.defaultStyles.textBaseline;
    this.lineHeight = void 0;
  }
  _setLines() {
    this.lines = splitText(this.text);
  }
  get font() {
    if (this._font == null || this._dirtyFont) {
      this._dirtyFont = false;
      this._font = getFont(this);
    }
    return this._font;
  }
  computeBBox() {
    return HdpiCanvas.has.textMetrics ? getPreciseBBox(this.lines, this.x, this.y, this) : getApproximateBBox(this.lines, this.x, this.y, this);
  }
  getLineHeight(line) {
    var _a, _b;
    if (this.lineHeight)
      return this.lineHeight;
    if (HdpiCanvas.has.textMetrics) {
      const metrics = HdpiCanvas.measureText(line, this.font, this.textBaseline, this.textAlign);
      return ((_a = metrics.fontBoundingBoxAscent) != null ? _a : metrics.emHeightAscent) + ((_b = metrics.fontBoundingBoxDescent) != null ? _b : metrics.emHeightDescent);
    }
    return HdpiCanvas.getTextSize(line, this.font).height;
  }
  isPointInPath(x, y) {
    const point = this.transformPoint(x, y);
    const bbox = this.computeBBox();
    return bbox ? bbox.containsPoint(point.x, point.y) : false;
  }
  render(renderCtx) {
    const { ctx, forceRender, stats } = renderCtx;
    if (this.dirty === 0 && !forceRender) {
      if (stats)
        stats.nodesSkipped += this.nodeCount.count;
      return;
    }
    if (!this.lines.length || !this.layerManager) {
      if (stats)
        stats.nodesSkipped += this.nodeCount.count;
      return;
    }
    this.computeTransformMatrix();
    this.matrix.toContext(ctx);
    const { fill, stroke, strokeWidth } = this;
    ctx.font = this.font;
    ctx.textAlign = this.textAlign;
    ctx.textBaseline = this.textBaseline;
    const pixelRatio = this.layerManager.canvas.pixelRatio || 1;
    const { globalAlpha } = ctx;
    if (fill) {
      ctx.fillStyle = fill;
      ctx.globalAlpha = globalAlpha * this.opacity * this.fillOpacity;
      const { fillShadow } = this;
      if (fillShadow == null ? void 0 : fillShadow.enabled) {
        ctx.shadowColor = fillShadow.color;
        ctx.shadowOffsetX = fillShadow.xOffset * pixelRatio;
        ctx.shadowOffsetY = fillShadow.yOffset * pixelRatio;
        ctx.shadowBlur = fillShadow.blur * pixelRatio;
      }
      this.renderLines((line, x, y) => ctx.fillText(line, x, y));
    }
    if (stroke && strokeWidth) {
      ctx.strokeStyle = stroke;
      ctx.lineWidth = strokeWidth;
      ctx.globalAlpha = globalAlpha * this.opacity * this.strokeOpacity;
      const { lineDash, lineDashOffset, lineCap, lineJoin } = this;
      if (lineDash) {
        ctx.setLineDash(lineDash);
      }
      if (lineDashOffset) {
        ctx.lineDashOffset = lineDashOffset;
      }
      if (lineCap) {
        ctx.lineCap = lineCap;
      }
      if (lineJoin) {
        ctx.lineJoin = lineJoin;
      }
      this.renderLines((line, x, y) => ctx.strokeText(line, x, y));
    }
    super.render(renderCtx);
  }
  renderLines(renderCallback) {
    const { lines, x, y } = this;
    const lineHeights = this.lines.map((line) => this.getLineHeight(line));
    const totalHeight = lineHeights.reduce((a, b) => a + b, 0);
    let offsetY = -(totalHeight - lineHeights[0]) * getVerticalOffset(this.textBaseline);
    for (let i = 0; i < lines.length; i++) {
      renderCallback(lines[i], x, y + offsetY);
      offsetY += lineHeights[i];
    }
  }
  static wrapLines(text, maxWidth, maxHeight, textProps, wrapping, overflow) {
    const canOverflow = overflow !== "hide";
    const font = getFont(textProps);
    const measurer = createTextMeasurer(font);
    const lines = text.split(/\r?\n/g);
    if (lines.length === 0) {
      return { lines: void 0, truncated: false };
    }
    if (wrapping === "never") {
      const { text: text2, truncated: truncated2 } = _Text2.truncateLine(lines[0], maxWidth, measurer, canOverflow ? "auto" : "never");
      return { lines: text2 != null ? [text2] : void 0, truncated: truncated2 };
    }
    const wrappedLines = [];
    let cumulativeHeight = 0;
    let truncated = false;
    for (const line of lines) {
      const wrappedLine = _Text2.wrapLine(
        line,
        maxWidth,
        maxHeight,
        measurer,
        textProps,
        wrapping,
        cumulativeHeight,
        canOverflow
      );
      if (wrappedLine == null) {
        return { lines: void 0, truncated: false };
      }
      wrappedLines.push(...wrappedLine.result);
      cumulativeHeight = wrappedLine.cumulativeHeight;
      if (wrappedLine.truncated) {
        truncated = true;
        break;
      }
    }
    return { lines: wrappedLines, truncated };
  }
  static wrap(text, maxWidth, maxHeight, textProps, wrapping, overflow = "ellipsis") {
    const { lines, truncated } = _Text2.wrapLines(text, maxWidth, maxHeight, textProps, wrapping, overflow);
    return { text: lines != null ? lines.join("\n").trim() : "", truncated };
  }
  static wrapLine(text, maxWidth, maxHeight, measurer, textProps, wrapping, cumulativeHeight, canOverflow) {
    text = text.trim();
    if (!text) {
      return { result: [], truncated: false, cumulativeHeight };
    }
    const initialSize = measurer.size(text);
    if (initialSize.width <= maxWidth) {
      return {
        result: [text],
        truncated: false,
        cumulativeHeight: cumulativeHeight + initialSize.height
      };
    }
    if (initialSize.height > maxHeight || measurer.width("W") > maxWidth) {
      return canOverflow ? { result: [], truncated: true, cumulativeHeight } : void 0;
    }
    const words = text.split(/\s+/g);
    const wrapResult = _Text2.wrapLineSequentially(
      words,
      maxWidth,
      maxHeight,
      measurer,
      textProps,
      wrapping,
      cumulativeHeight,
      canOverflow
    );
    if (wrapResult == null) {
      return void 0;
    }
    cumulativeHeight = wrapResult.cumulativeHeight;
    let { lines } = wrapResult;
    if (!(wrapResult.wordsBrokenOrTruncated || wrapResult.linesTruncated)) {
      const linesCount = wrapResult.lines.length;
      const balanced = _Text2.wrapLineBalanced(words, maxWidth, measurer, linesCount);
      if (balanced.length === lines.length) {
        lines = balanced;
      }
    }
    const wrappedText = lines.map((ln) => ln.join(" "));
    return { result: wrappedText, truncated: wrapResult.linesTruncated, cumulativeHeight };
  }
  static breakWord(word, firstLineWidth, maxWidth, hyphens, measurer) {
    const isPunctuationAt = (index) => _Text2.punctuationMarks.includes(word[index]);
    const h = hyphens ? measurer.width("-") : 0;
    const breaks = [];
    let partWidth = 0;
    let p = 0;
    for (let i = 0; i < word.length; i++) {
      const c = word[i];
      const w = measurer.width(c);
      const limit = p === 0 ? firstLineWidth : maxWidth;
      if (partWidth + w + h > limit) {
        breaks.push(i);
        partWidth = 0;
        p++;
      }
      partWidth += w;
    }
    const parts = [];
    let start = 0;
    for (const index of breaks) {
      let part = word.substring(start, index);
      if (hyphens && part.length > 0 && !isPunctuationAt(index - 1) && !isPunctuationAt(index)) {
        part += "-";
      }
      parts.push(part);
      start = index;
    }
    parts.push(word.substring(start));
    return parts;
  }
  static truncateLine(text, maxWidth, measurer, ellipsisMode) {
    text = text.trimEnd();
    const lineWidth = measurer.width(text);
    if (lineWidth > maxWidth && ellipsisMode === "never") {
      return { text: void 0, truncated: false };
    } else if (lineWidth <= maxWidth && ellipsisMode !== "force") {
      return { text, truncated: false };
    }
    const ellipsisWidth = measurer.width(ellipsis);
    let trunc = text;
    let truncWidth = lineWidth;
    while (trunc.length > 0 && truncWidth + ellipsisWidth > maxWidth) {
      trunc = trunc.slice(0, -1).trimEnd();
      truncWidth = measurer.width(trunc);
    }
    if (truncWidth + ellipsisWidth <= maxWidth) {
      return { text: `${trunc}${ellipsis}`, truncated: true };
    } else {
      return { text: void 0, truncated: false };
    }
  }
  static wrapLineSequentially(words, maxWidth, maxHeight, measurer, textProps, wrapping, cumulativeHeight, canOverflow) {
    const { fontSize = 0, lineHeight = fontSize * _Text2.defaultLineHeightRatio } = textProps;
    const breakWord = wrapping === "always" || wrapping === "hyphenate";
    const hyphenate = wrapping === "hyphenate";
    const spaceWidth = measurer.width(" ");
    let wordsBrokenOrTruncated = false;
    let linesTruncated = false;
    const lines = [];
    let currentLine = [];
    let lineWidth = 0;
    const getReturnValue = () => ({
      lines,
      linesTruncated,
      wordsBrokenOrTruncated,
      cumulativeHeight
    });
    const truncateLastLine = () => {
      if (!canOverflow) {
        return void 0;
      }
      const lastLine = currentLine.join(" ");
      const { text } = _Text2.truncateLine(lastLine, maxWidth, measurer, "force");
      if (text == null) {
        return void 0;
      }
      currentLine.splice(0, currentLine.length, text);
      linesTruncated = true;
      return getReturnValue();
    };
    const addNewLine = () => {
      const expectedHeight = cumulativeHeight + lineHeight;
      if (expectedHeight >= maxHeight) {
        return false;
      }
      currentLine = [];
      lineWidth = 0;
      cumulativeHeight = expectedHeight;
      lines.push(currentLine);
      return true;
    };
    if (!addNewLine()) {
      return truncateLastLine();
    }
    for (let i = 0; i < words.length; i++) {
      const word = words[i];
      const wordWidth = measurer.width(word);
      const expectedSpaceWidth = currentLine.length === 0 ? 0 : spaceWidth;
      const expectedLineWidth = lineWidth + expectedSpaceWidth + wordWidth;
      if (expectedLineWidth <= maxWidth) {
        currentLine.push(word);
        lineWidth = expectedLineWidth;
        continue;
      }
      if (wordWidth <= maxWidth) {
        if (!addNewLine()) {
          return truncateLastLine();
        }
        currentLine.push(word);
        lineWidth = wordWidth;
        continue;
      }
      wordsBrokenOrTruncated = true;
      if (breakWord) {
        const availWidth = maxWidth - lineWidth - expectedSpaceWidth;
        const parts = _Text2.breakWord(word, availWidth, maxWidth, hyphenate, measurer);
        for (let p = 0; p < parts.length; p++) {
          const part = parts[p];
          part && currentLine.push(part);
          if (p === parts.length - 1) {
            lineWidth = measurer.width(part);
          } else if (!addNewLine()) {
            return truncateLastLine();
          }
        }
      } else if (canOverflow) {
        if (!addNewLine()) {
          return truncateLastLine();
        }
        const { text } = _Text2.truncateLine(word, maxWidth, measurer, "force");
        if (text == null) {
          return void 0;
        }
        currentLine.push(text);
        if (i < words.length - 1) {
          linesTruncated = true;
        }
        break;
      } else {
        return void 0;
      }
    }
    return getReturnValue();
  }
  static wrapLineBalanced(words, maxWidth, measurer, linesCount) {
    const totalWordsWidth = words.reduce((sum2, w) => sum2 + measurer.width(w), 0);
    const spaceWidth = measurer.width(" ");
    const totalSpaceWidth = spaceWidth * (words.length - linesCount - 2);
    const averageLineWidth = (totalWordsWidth + totalSpaceWidth) / linesCount;
    const lines = [];
    let currentLine = [];
    let lineWidth = measurer.width(words[0]);
    let newLine = true;
    for (const word of words) {
      const width = measurer.width(word);
      if (newLine) {
        currentLine = [];
        currentLine.push(word);
        lineWidth = width;
        newLine = false;
        lines.push(currentLine);
        continue;
      }
      const expectedLineWidth = lineWidth + spaceWidth + width;
      if (expectedLineWidth <= averageLineWidth) {
        currentLine.push(word);
        lineWidth = expectedLineWidth;
      } else if (expectedLineWidth <= maxWidth) {
        currentLine.push(word);
        newLine = true;
      } else {
        currentLine = [word];
        lineWidth = width;
        lines.push(currentLine);
      }
    }
    return lines;
  }
  setFont(props) {
    this.fontFamily = props.fontFamily;
    this.fontSize = props.fontSize;
    this.fontStyle = props.fontStyle;
    this.fontWeight = props.fontWeight;
  }
  setAlign(props) {
    this.textAlign = props.textAlign;
    this.textBaseline = props.textBaseline;
  }
};
_Text.className = "Text";
_Text.defaultLineHeightRatio = 1.15;
_Text.defaultStyles = Object.assign({}, Shape.defaultStyles, {
  textAlign: "start",
  fontStyle: void 0,
  fontWeight: void 0,
  fontSize: 10,
  fontFamily: "sans-serif",
  textBaseline: "alphabetic"
});
_Text.ellipsis = ellipsis;
_Text.punctuationMarks = [".", ",", "-", ":", ";", "!", "?", `'`, '"', "(", ")"];
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], _Text.prototype, "x", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], _Text.prototype, "y", 2);
__decorateClass([
  SceneChangeDetection({ redraw: 3, changeCb: (o) => o._setLines() })
], _Text.prototype, "text", 2);
__decorateClass([
  SceneFontChangeDetection()
], _Text.prototype, "fontStyle", 2);
__decorateClass([
  SceneFontChangeDetection()
], _Text.prototype, "fontWeight", 2);
__decorateClass([
  SceneFontChangeDetection()
], _Text.prototype, "fontSize", 2);
__decorateClass([
  SceneFontChangeDetection()
], _Text.prototype, "fontFamily", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], _Text.prototype, "textAlign", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], _Text.prototype, "textBaseline", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], _Text.prototype, "lineHeight", 2);
var Text = _Text;
function createTextMeasurer(font) {
  const cache = /* @__PURE__ */ new Map();
  const getTextSize = (text) => HdpiCanvas.getTextSize(text, font);
  const getLineWidth = (text) => {
    if (cache.has(text)) {
      return cache.get(text);
    }
    const { width } = getTextSize(text);
    cache.set(text, width);
    return width;
  };
  return { size: getTextSize, width: getLineWidth };
}
function getFont(fontProps) {
  const { fontFamily, fontSize, fontStyle, fontWeight } = fontProps;
  return [fontStyle != null ? fontStyle : "", fontWeight != null ? fontWeight : "", fontSize + "px", fontFamily].join(" ").trim();
}
function measureText(lines, x, y, textProps) {
  return HdpiCanvas.has.textMetrics ? getPreciseBBox(lines, x, y, textProps) : getApproximateBBox(lines, x, y, textProps);
}
function getPreciseBBox(lines, x, y, textProps) {
  var _a, _b;
  let left = 0;
  let top = 0;
  let width = 0;
  let height = 0;
  let baselineDistance = 0;
  const font = getFont(textProps);
  const {
    lineHeight,
    textBaseline = Text.defaultStyles.textBaseline,
    textAlign = Text.defaultStyles.textAlign
  } = textProps;
  for (let i = 0; i < lines.length; i++) {
    const metrics = HdpiCanvas.measureText(lines[i], font, textBaseline, textAlign);
    left = Math.max(left, metrics.actualBoundingBoxLeft);
    width = Math.max(width, metrics.width);
    if (i == 0) {
      top += metrics.actualBoundingBoxAscent;
      height += metrics.actualBoundingBoxAscent;
    } else {
      baselineDistance += (_a = metrics.fontBoundingBoxAscent) != null ? _a : metrics.emHeightAscent;
    }
    if (i == lines.length - 1) {
      height += metrics.actualBoundingBoxDescent;
    } else {
      baselineDistance += (_b = metrics.fontBoundingBoxDescent) != null ? _b : metrics.emHeightDescent;
    }
  }
  if (lineHeight !== void 0) {
    baselineDistance = (lines.length - 1) * lineHeight;
  }
  height += baselineDistance;
  top += baselineDistance * getVerticalOffset(textBaseline);
  return new BBox(x - left, y - top, width, height);
}
function getApproximateBBox(lines, x, y, textProps) {
  let width = 0;
  let firstLineHeight = 0;
  let baselineDistance = 0;
  const font = getFont(textProps);
  const {
    lineHeight,
    textBaseline = Text.defaultStyles.textBaseline,
    textAlign = Text.defaultStyles.textAlign
  } = textProps;
  if (lines.length > 0) {
    const lineSize = HdpiCanvas.getTextSize(lines[0], font);
    width = lineSize.width;
    firstLineHeight = lineSize.height;
  }
  for (let i = 1; i < lines.length; i++) {
    const lineSize = HdpiCanvas.getTextSize(lines[i], font);
    width = Math.max(width, lineSize.width);
    baselineDistance += lineHeight != null ? lineHeight : lineSize.height;
  }
  switch (textAlign) {
    case "end":
    case "right":
      x -= width;
      break;
    case "center":
      x -= width / 2;
  }
  switch (textBaseline) {
    case "alphabetic":
      y -= firstLineHeight * 0.7 + baselineDistance * 0.5;
      break;
    case "middle":
      y -= firstLineHeight * 0.45 + baselineDistance * 0.5;
      break;
    case "ideographic":
      y -= firstLineHeight + baselineDistance;
      break;
    case "hanging":
      y -= firstLineHeight * 0.2 + baselineDistance * 0.5;
      break;
    case "bottom":
      y -= firstLineHeight + baselineDistance;
      break;
  }
  return new BBox(x, y, width, firstLineHeight + baselineDistance);
}
function getVerticalOffset(textBaseline) {
  switch (textBaseline) {
    case "top":
    case "hanging":
      return 0;
    case "bottom":
    case "alphabetic":
    case "ideographic":
      return 1;
    case "middle":
      return 0.5;
  }
}
function splitText(text) {
  return typeof text === "string" ? text.split(/\r?\n/g) : [];
}
function ProxyProperty(...proxyProperties) {
  const property = proxyProperties[proxyProperties.length - 1];
  if (proxyProperties.length === 1) {
    return addTransformToInstanceProperty(
      (target, _, value) => {
        target[property] = value;
        return value;
      },
      (target, _) => {
        return target[property];
      }
    );
  }
  const getTarget = (target) => {
    let value = target;
    for (let i = 0; i < proxyProperties.length - 1; i += 1) {
      value = value[proxyProperties[i]];
    }
    return value;
  };
  return addTransformToInstanceProperty(
    (target, _, value) => {
      getTarget(target)[property] = value;
      return value;
    },
    (target, _) => {
      return getTarget(target)[property];
    }
  );
}
function ProxyOnWrite(proxyProperty) {
  return addTransformToInstanceProperty((target, _, value) => {
    target[proxyProperty] = value;
    return value;
  });
}
function ProxyPropertyOnWrite(childName, childProperty) {
  return addTransformToInstanceProperty((target, key, value) => {
    target[childName][childProperty != null ? childProperty : key] = value;
    return value;
  });
}
function ActionOnSet(opts) {
  const { newValue: newValueFn, oldValue: oldValueFn, changeValue: changeValueFn } = opts;
  return addTransformToInstanceProperty((target, _, newValue, oldValue) => {
    if (newValue !== oldValue) {
      if (oldValue !== void 0) {
        oldValueFn == null ? void 0 : oldValueFn.call(target, oldValue);
      }
      if (newValue !== void 0) {
        newValueFn == null ? void 0 : newValueFn.call(target, newValue);
      }
      changeValueFn == null ? void 0 : changeValueFn.call(target, newValue, oldValue);
    }
    return newValue;
  });
}
function injectStyle(document2, cssStyle) {
  const styleElement = document2.createElement("style");
  styleElement.innerHTML = cssStyle;
  document2.head.insertBefore(styleElement, document2.head.querySelector("style"));
}
var DEFAULT_TOOLTIP_CLASS = "ag-chart-tooltip";
var DEFAULT_TOOLTIP_DARK_CLASS = "ag-chart-dark-tooltip";
var defaultTooltipCss = `
.${DEFAULT_TOOLTIP_CLASS} {
    transition: transform 0.1s ease;
    max-width: 100%;
    position: fixed;
    left: 0px;
    top: 0px;
    z-index: 99999;
    font: 12px Verdana, sans-serif;
    color: rgb(70, 70, 70);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
}

.${DEFAULT_TOOLTIP_CLASS}-wrap-always {
    overflow-wrap: break-word;
    word-break: break-word;
    hyphens: none;
}

.${DEFAULT_TOOLTIP_CLASS}-wrap-hyphenate {
    overflow-wrap: break-word;
    word-break: break-word;
    hyphens: auto;
}

.${DEFAULT_TOOLTIP_CLASS}-wrap-on-space {
    overflow-wrap: normal;
    word-break: normal;
}

.${DEFAULT_TOOLTIP_CLASS}-wrap-never {
    white-space: pre;
    text-overflow: ellipsis;
}

.${DEFAULT_TOOLTIP_CLASS}-no-interaction {
    pointer-events: none;
    user-select: none;
}

.${DEFAULT_TOOLTIP_CLASS}-no-animation {
    transition: none !important;
}

.${DEFAULT_TOOLTIP_CLASS}-hidden {
    visibility: hidden;
}

.${DEFAULT_TOOLTIP_CLASS}-title {
    overflow: hidden;
    position: relative;
    padding: 8px 14px;
    border-top-left-radius: 2px;
    border-top-right-radius: 2px;
    color: white;
    background-color: #888888;
    z-index: 1;
    text-overflow: inherit;
}

.${DEFAULT_TOOLTIP_CLASS}-title:only-child {
    border-bottom-left-radius: 2px;
    border-bottom-right-radius: 2px;
}

.${DEFAULT_TOOLTIP_CLASS}-content {
    overflow: hidden;
    padding: 6px 14px;
    line-height: 1.7em;
    background: white;
    border-bottom-left-radius: 2px;
    border-bottom-right-radius: 2px;
    border: 1px solid rgba(0, 0, 0, 0.15);
    overflow: hidden;
    text-overflow: inherit;
}

.${DEFAULT_TOOLTIP_CLASS}-arrow::before {
    content: "";

    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);

    border: 5px solid #d9d9d9;

    border-left-color: transparent;
    border-right-color: transparent;
    border-bottom-color: transparent;

    width: 0;
    height: 0;

    margin: 0 auto;
}

.${DEFAULT_TOOLTIP_CLASS}-arrow::after {
    content: "";

    position: absolute;
    top: calc(100% - 1px);
    left: 50%;
    transform: translateX(-50%);

    border: 5px solid white;

    border-left-color: transparent;
    border-right-color: transparent;
    border-bottom-color: transparent;

    width: 0;
    height: 0;

    margin: 0 auto;
}

.${DEFAULT_TOOLTIP_CLASS}.${DEFAULT_TOOLTIP_DARK_CLASS} {
    color: white;
    background: #15181c;
}

.${DEFAULT_TOOLTIP_CLASS}.${DEFAULT_TOOLTIP_DARK_CLASS} .${DEFAULT_TOOLTIP_CLASS}-content {
    border-color: rgba(255, 255, 255, 0.15);
}

.ag-chart-wrapper {
    box-sizing: border-box;
    overflow: hidden;
}
`;
function toTooltipHtml(input, defaults) {
  var _a, _b, _c;
  if (typeof input === "string") {
    return input;
  }
  const {
    content = (_a = defaults == null ? void 0 : defaults.content) != null ? _a : "",
    title = defaults == null ? void 0 : defaults.title,
    color = (_b = defaults == null ? void 0 : defaults.color) != null ? _b : "white",
    backgroundColor = (_c = defaults == null ? void 0 : defaults.backgroundColor) != null ? _c : "#888"
  } = input;
  const titleHtml = title ? `<div class="${DEFAULT_TOOLTIP_CLASS}-title"
        style="color: ${color}; background-color: ${backgroundColor}">${title}</div>` : "";
  const contentHtml = content ? `<div class="${DEFAULT_TOOLTIP_CLASS}-content">${content}</div>` : "";
  return `${titleHtml}${contentHtml}`;
}
var TooltipPosition = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.type = "pointer";
    this.xOffset = 0;
    this.yOffset = 0;
  }
};
__decorateClass([
  Validate(UNION(["pointer", "node"], "a position type"))
], TooltipPosition.prototype, "type", 2);
__decorateClass([
  Validate(NUMBER)
], TooltipPosition.prototype, "xOffset", 2);
__decorateClass([
  Validate(NUMBER)
], TooltipPosition.prototype, "yOffset", 2);
var _Tooltip = class _Tooltip2 {
  constructor(canvasElement, document2, window2, container) {
    this.enableInteraction = false;
    this.enabled = true;
    this.showArrow = void 0;
    this.class = void 0;
    this.lastClass = void 0;
    this.delay = 0;
    this.range = "nearest";
    this.wrapping = "hyphenate";
    this.lastVisibilityChange = Date.now();
    this.position = new TooltipPosition();
    this.showTimeout = 0;
    this._showArrow = true;
    this.tooltipRoot = container;
    this.window = window2;
    const element2 = document2.createElement("div");
    this.element = this.tooltipRoot.appendChild(element2);
    this.element.classList.add(DEFAULT_TOOLTIP_CLASS);
    this.canvasElement = canvasElement;
    if (typeof IntersectionObserver !== "undefined") {
      const observer = new IntersectionObserver(
        (entries) => {
          for (const entry of entries) {
            if (entry.target === this.canvasElement && entry.intersectionRatio === 0) {
              this.toggle(false);
            }
          }
        },
        { root: this.tooltipRoot }
      );
      observer.observe(this.canvasElement);
      this.observer = observer;
    }
    if (_Tooltip2.tooltipDocuments.indexOf(document2) < 0) {
      injectStyle(document2, defaultTooltipCss);
      _Tooltip2.tooltipDocuments.push(document2);
    }
  }
  destroy() {
    const { parentNode } = this.element;
    if (parentNode) {
      parentNode.removeChild(this.element);
    }
    if (this.observer) {
      this.observer.unobserve(this.canvasElement);
    }
  }
  isVisible() {
    const { element: element2 } = this;
    return !element2.classList.contains(DEFAULT_TOOLTIP_CLASS + "-hidden");
  }
  updateClass(visible, showArrow, addCustomClass = true) {
    const { element: element2, class: newClass, lastClass, enableInteraction, lastVisibilityChange } = this;
    const wasVisible = this.isVisible();
    const nowVisible = !!visible;
    let timeSinceLastVisibilityChangeMs = Infinity;
    if (wasVisible !== nowVisible) {
      const now = Date.now();
      timeSinceLastVisibilityChangeMs = now - lastVisibilityChange;
      this.lastVisibilityChange = now;
    }
    const toggleClass = (name, include) => {
      const className = `${DEFAULT_TOOLTIP_CLASS}-${name}`;
      if (include) {
        element2.classList.add(className);
      } else {
        element2.classList.remove(className);
      }
    };
    const animatedMoveThresholdMs = 100;
    const thrashingThresholdMs = 5;
    const noAnimation = !wasVisible && nowVisible && timeSinceLastVisibilityChangeMs > animatedMoveThresholdMs;
    if (timeSinceLastVisibilityChangeMs > thrashingThresholdMs) {
      toggleClass("no-animation", noAnimation);
    }
    toggleClass("no-interaction", !enableInteraction);
    toggleClass("hidden", !visible);
    toggleClass("arrow", !!showArrow);
    this.updateWrapping();
    if (addCustomClass) {
      if (newClass !== lastClass) {
        if (lastClass) {
          element2.classList.remove(lastClass);
        }
        if (newClass) {
          element2.classList.add(newClass);
        }
      }
      this.lastClass = newClass;
    } else {
      if (lastClass) {
        element2.classList.remove(lastClass);
      }
      this.lastClass = void 0;
    }
  }
  updateWrapping() {
    const { element: element2, wrapping } = this;
    const wrappingOptions = {
      always: false,
      hyphenate: false,
      "on-space": false,
      never: false
    };
    wrappingOptions[wrapping] = true;
    Object.entries(wrappingOptions).forEach(([name, force]) => {
      element2.classList.toggle(`${DEFAULT_TOOLTIP_CLASS}-wrap-${name}`, force);
    });
  }
  /**
   * Shows tooltip at the given event's coordinates.
   * If the `html` parameter is missing, moves the existing tooltip to the new position.
   */
  show(meta, html, instantly = false) {
    var _a, _b, _c, _d, _e, _f, _g;
    const { element: element2, canvasElement } = this;
    if (html !== void 0) {
      element2.innerHTML = html;
    } else if (!element2.innerHTML) {
      this.toggle(false);
      return;
    }
    const limit = (low, actual, high) => {
      return Math.max(Math.min(actual, high), low);
    };
    const xOffset = (_b = (_a = meta.position) == null ? void 0 : _a.xOffset) != null ? _b : 0;
    const yOffset = (_d = (_c = meta.position) == null ? void 0 : _c.yOffset) != null ? _d : 0;
    const canvasRect = canvasElement.getBoundingClientRect();
    const naiveLeft = canvasRect.left + meta.offsetX - element2.clientWidth / 2 + xOffset;
    const naiveTop = canvasRect.top + meta.offsetY - element2.clientHeight - 8 + yOffset;
    const windowBounds = this.getWindowBoundingBox();
    const maxLeft = windowBounds.x + windowBounds.width - element2.clientWidth - 1;
    const maxTop = windowBounds.y + windowBounds.height - element2.clientHeight;
    const left = limit(windowBounds.x, naiveLeft, maxLeft);
    const top = limit(windowBounds.y, naiveTop, maxTop);
    const constrained = left !== naiveLeft || top !== naiveTop;
    const defaultShowArrow = !constrained && !xOffset && !yOffset;
    const showArrow = (_f = (_e = meta.showArrow) != null ? _e : this.showArrow) != null ? _f : defaultShowArrow;
    this.updateShowArrow(showArrow);
    element2.style.transform = `translate(${Math.round(left)}px, ${Math.round(top)}px)`;
    this.enableInteraction = (_g = meta.enableInteraction) != null ? _g : false;
    if (this.delay > 0 && !instantly) {
      this.toggle(false);
      this.showTimeout = this.window.setTimeout(() => {
        this.toggle(true, meta.addCustomClass);
      }, this.delay);
      return;
    }
    this.toggle(true, meta.addCustomClass);
  }
  getWindowBoundingBox() {
    return new BBox(0, 0, this.window.innerWidth, this.window.innerHeight);
  }
  toggle(visible, addCustomClass) {
    if (!visible) {
      this.window.clearTimeout(this.showTimeout);
    }
    this.updateClass(visible, this._showArrow, addCustomClass);
  }
  pointerLeftOntoTooltip(event) {
    var _a;
    if (!this.enableInteraction)
      return false;
    const classList = (_a = event.sourceEvent.relatedTarget) == null ? void 0 : _a.classList;
    const classes = ["", "-title", "-content"];
    const classListContains = Boolean(classes.filter((c) => classList == null ? void 0 : classList.contains(`${DEFAULT_TOOLTIP_CLASS}${c}`)));
    return classList !== void 0 && classListContains;
  }
  updateShowArrow(show) {
    this._showArrow = show;
  }
};
_Tooltip.tooltipDocuments = [];
__decorateClass([
  Validate(BOOLEAN)
], _Tooltip.prototype, "enabled", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], _Tooltip.prototype, "showArrow", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], _Tooltip.prototype, "class", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], _Tooltip.prototype, "delay", 2);
__decorateClass([
  Validate(INTERACTION_RANGE)
], _Tooltip.prototype, "range", 2);
__decorateClass([
  Validate(TEXT_WRAP)
], _Tooltip.prototype, "wrapping", 2);
var Tooltip = _Tooltip;
var Caption = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.id = createId(this);
    this.node = new Text().setProperties({
      textAlign: "center",
      pointerEvents: 1
      /* None */
    });
    this.enabled = false;
    this.textAlign = "center";
    this.fontSize = 10;
    this.fontFamily = "sans-serif";
    this.wrapping = "always";
    this.truncated = false;
  }
  registerInteraction(moduleCtx) {
    return moduleCtx.interactionManager.addListener("hover", (event) => this.handleMouseMove(moduleCtx, event));
  }
  computeTextWrap(containerWidth, containerHeight) {
    var _a, _b;
    const { text, wrapping } = this;
    const maxWidth = Math.min((_a = this.maxWidth) != null ? _a : Infinity, containerWidth);
    const maxHeight = (_b = this.maxHeight) != null ? _b : containerHeight;
    if (!isFinite(maxWidth) && !isFinite(maxHeight)) {
      this.node.text = text;
      return;
    }
    const { text: wrappedText, truncated } = Text.wrap(text != null ? text : "", maxWidth, maxHeight, this, wrapping);
    this.node.text = wrappedText;
    this.truncated = truncated;
  }
  handleMouseMove(moduleCtx, event) {
    if (!this.enabled) {
      return;
    }
    const bbox = this.node.computeBBox();
    const { pageX, pageY, offsetX, offsetY } = event;
    const pointerInsideCaption = this.node.visible && bbox.containsPoint(offsetX, offsetY);
    if (!pointerInsideCaption) {
      moduleCtx.tooltipManager.removeTooltip(this.id);
      return;
    }
    event.consume();
    if (!this.truncated) {
      moduleCtx.tooltipManager.removeTooltip(this.id);
      return;
    }
    moduleCtx.tooltipManager.updateTooltip(
      this.id,
      { pageX, pageY, offsetX, offsetY, event, showArrow: false, addCustomClass: false },
      toTooltipHtml({ content: this.text })
    );
  }
};
Caption.SMALL_PADDING = 10;
Caption.LARGE_PADDING = 20;
__decorateClass([
  Validate(BOOLEAN)
], Caption.prototype, "enabled", 2);
__decorateClass([
  Validate(STRING, { optional: true }),
  ProxyPropertyOnWrite("node")
], Caption.prototype, "text", 2);
__decorateClass([
  Validate(TEXT_ALIGN, { optional: true }),
  ProxyPropertyOnWrite("node")
], Caption.prototype, "textAlign", 2);
__decorateClass([
  Validate(FONT_STYLE, { optional: true }),
  ProxyPropertyOnWrite("node")
], Caption.prototype, "fontStyle", 2);
__decorateClass([
  Validate(FONT_WEIGHT, { optional: true }),
  ProxyPropertyOnWrite("node")
], Caption.prototype, "fontWeight", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER),
  ProxyPropertyOnWrite("node")
], Caption.prototype, "fontSize", 2);
__decorateClass([
  Validate(STRING),
  ProxyPropertyOnWrite("node")
], Caption.prototype, "fontFamily", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true }),
  ProxyPropertyOnWrite("node", "fill")
], Caption.prototype, "color", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], Caption.prototype, "spacing", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], Caption.prototype, "lineHeight", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], Caption.prototype, "maxWidth", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], Caption.prototype, "maxHeight", 2);
__decorateClass([
  Validate(TEXT_WRAP)
], Caption.prototype, "wrapping", 2);
var AxisTitle = class {
  constructor() {
    this.enabled = false;
    this.spacing = Caption.SMALL_PADDING;
    this.fontSize = 10;
    this.fontFamily = "sans-serif";
    this.wrapping = "always";
  }
};
__decorateClass([
  Validate(BOOLEAN)
], AxisTitle.prototype, "enabled", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], AxisTitle.prototype, "text", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], AxisTitle.prototype, "spacing", 2);
__decorateClass([
  Validate(FONT_STYLE, { optional: true })
], AxisTitle.prototype, "fontStyle", 2);
__decorateClass([
  Validate(FONT_WEIGHT, { optional: true })
], AxisTitle.prototype, "fontWeight", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], AxisTitle.prototype, "fontSize", 2);
__decorateClass([
  Validate(STRING)
], AxisTitle.prototype, "fontFamily", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], AxisTitle.prototype, "color", 2);
__decorateClass([
  Validate(TEXT_WRAP)
], AxisTitle.prototype, "wrapping", 2);
__decorateClass([
  Validate(FUNCTION, { optional: true })
], AxisTitle.prototype, "formatter", 2);
var JSON_APPLY_PLUGINS = {
  constructors: {},
  constructedArrays: /* @__PURE__ */ new WeakMap()
};
function assignJsonApplyConstructedArray(array, ctor) {
  var _a;
  (_a = JSON_APPLY_PLUGINS.constructedArrays) == null ? void 0 : _a.set(array, ctor);
}
var JSON_APPLY_OPTIONS = {
  constructors: {
    "axes[].title": AxisTitle
  },
  allowedTypes: {
    "legend.pagination.marker.shape": ["primitive", "function"],
    "axis[].tick.count": ["primitive", "class-instance"]
  }
};
function getJsonApplyOptions(ctx) {
  class CaptionWithContext extends Caption {
    constructor() {
      super();
      this.registerInteraction(ctx);
    }
  }
  return {
    constructors: __spreadValues(__spreadProps(__spreadValues({}, JSON_APPLY_OPTIONS.constructors), {
      title: CaptionWithContext,
      subtitle: CaptionWithContext,
      footnote: CaptionWithContext
    }), JSON_APPLY_PLUGINS.constructors),
    constructedArrays: JSON_APPLY_PLUGINS.constructedArrays,
    allowedTypes: __spreadValues({}, JSON_APPLY_OPTIONS.allowedTypes)
  };
}
var _ContinuousScale = class _ContinuousScale2 {
  constructor(domain, range3) {
    this.invalid = true;
    this.nice = false;
    this.interval = void 0;
    this.tickCount = _ContinuousScale2.defaultTickCount;
    this.minTickCount = 0;
    this.maxTickCount = Infinity;
    this.niceDomain = [];
    this.defaultClampMode = "raw";
    this.domain = domain;
    this.range = range3;
  }
  static is(value) {
    return value instanceof _ContinuousScale2;
  }
  transform(x) {
    return x;
  }
  transformInvert(x) {
    return x;
  }
  calcBandwidth(smallestInterval = 1) {
    const domain = this.getDomain();
    const maxRange = Math.max(...this.range);
    const intervals = Math.abs(domain[1] - domain[0]) / smallestInterval + 1;
    const maxBands = Math.floor(maxRange);
    const bands = Math.min(intervals, maxBands);
    return maxRange / Math.max(1, bands);
  }
  fromDomain(d) {
    if (typeof d === "number") {
      return d;
    } else if (d instanceof Date) {
      return d.getTime();
    }
    return NaN;
  }
  getDomain() {
    if (this.nice) {
      this.refresh();
      if (this.niceDomain.length) {
        return this.niceDomain;
      }
    }
    return this.domain;
  }
  convert(x, opts) {
    var _a;
    const clampMode = (_a = opts == null ? void 0 : opts.clampMode) != null ? _a : this.defaultClampMode;
    if (!this.domain || this.domain.length < 2) {
      return NaN;
    }
    this.refresh();
    const domain = this.getDomain().map((d) => this.transform(d));
    const [d0, d1] = domain;
    const { range: range3 } = this;
    const [r0, r1] = range3;
    x = this.transform(x);
    if (clampMode === "clamped") {
      const start = Math.min(this.fromDomain(d0), this.fromDomain(d1));
      const stop = Math.max(this.fromDomain(d0), this.fromDomain(d1));
      if (this.fromDomain(x) < start) {
        return r0;
      } else if (this.fromDomain(x) > stop) {
        return r1;
      }
    }
    if (d0 === d1) {
      return (r0 + r1) / 2;
    } else if (x === d0) {
      return r0;
    } else if (x === d1) {
      return r1;
    }
    return r0 + (this.fromDomain(x) - this.fromDomain(d0)) / (this.fromDomain(d1) - this.fromDomain(d0)) * (r1 - r0);
  }
  invert(x) {
    this.refresh();
    const domain = this.getDomain().map((d2) => this.transform(d2));
    const [d0, d1] = domain;
    const { range: range3 } = this;
    const [r0, r1] = range3;
    const isReversed = r0 > r1;
    const rMin = isReversed ? r1 : r0;
    const rMax = isReversed ? r0 : r1;
    let d;
    if (x < rMin) {
      return isReversed ? d1 : d0;
    } else if (x > rMax) {
      return isReversed ? d0 : d1;
    } else if (r0 === r1) {
      d = this.toDomain((this.fromDomain(d0) + this.fromDomain(d1)) / 2);
    } else {
      d = this.toDomain(
        this.fromDomain(d0) + (x - r0) / (r1 - r0) * (this.fromDomain(d1) - this.fromDomain(d0))
      );
    }
    return this.transformInvert(d);
  }
  refresh() {
    if (!this.invalid)
      return;
    this.invalid = false;
    this.update();
    if (this.invalid) {
      Logger.warnOnce("Expected update to not invalidate scale");
    }
  }
  getPixelRange() {
    const range3 = this.range.slice().sort((a, b) => a - b);
    return range3[1] - range3[0];
  }
  isDenseInterval({
    start,
    stop,
    interval,
    count: count2
  }) {
    const domain = stop - start;
    const availableRange = this.getPixelRange();
    const step = typeof interval === "number" ? interval : 1;
    count2 != null ? count2 : count2 = domain / step;
    if (count2 >= availableRange) {
      Logger.warn(
        `the configured interval results in more than 1 item per pixel, ignoring. Supply a larger interval or omit this configuration`
      );
      return true;
    }
    return false;
  }
};
_ContinuousScale.defaultTickCount = 5;
_ContinuousScale.defaultMaxTickCount = 6;
__decorateClass([
  Invalidating
], _ContinuousScale.prototype, "domain", 2);
__decorateClass([
  Invalidating
], _ContinuousScale.prototype, "range", 2);
__decorateClass([
  Invalidating
], _ContinuousScale.prototype, "nice", 2);
__decorateClass([
  Invalidating
], _ContinuousScale.prototype, "interval", 2);
__decorateClass([
  Invalidating
], _ContinuousScale.prototype, "tickCount", 2);
__decorateClass([
  Invalidating
], _ContinuousScale.prototype, "minTickCount", 2);
__decorateClass([
  Invalidating
], _ContinuousScale.prototype, "maxTickCount", 2);
var ContinuousScale = _ContinuousScale;
function ascendingStringNumberUndefined(a, b) {
  let diff2 = 0;
  if (typeof a === "number" && typeof b === "number") {
    diff2 = a - b;
  } else if (typeof a === "string" && typeof b === "string") {
    diff2 = a.localeCompare(b);
  } else if (a == null && b == null) {
  } else if (a == null) {
    diff2 = -1;
  } else if (b == null) {
    diff2 = 1;
  } else {
    diff2 = String(a).localeCompare(String(b));
  }
  return diff2;
}
function compoundAscending(a, b, comparator) {
  const toLiteral = (v) => {
    if (typeof v === "function") {
      return v();
    }
    return v;
  };
  for (const idx in a) {
    const diff2 = comparator(toLiteral(a[idx]), toLiteral(b[idx]));
    if (diff2 !== 0) {
      return diff2;
    }
  }
  return 0;
}
var _Group = class _Group2 extends Node {
  constructor(opts) {
    var _a;
    super({ isVirtual: opts == null ? void 0 : opts.isVirtual });
    this.opts = opts;
    this.opacity = 1;
    this.lastBBox = void 0;
    const { zIndex, zIndexSubOrder } = opts != null ? opts : {};
    this.isContainerNode = true;
    if (zIndex !== void 0) {
      this.zIndex = zIndex;
    }
    if (zIndexSubOrder !== void 0) {
      this.zIndexSubOrder = zIndexSubOrder;
    }
    this.name = (_a = this.opts) == null ? void 0 : _a.name;
  }
  zIndexChanged() {
    var _a;
    if (this.layer) {
      (_a = this._layerManager) == null ? void 0 : _a.moveLayer(this.layer, this.zIndex, this.zIndexSubOrder);
    }
  }
  isLayer() {
    return this.layer != null;
  }
  _setLayerManager(scene) {
    var _a, _b;
    if (this._layerManager && this.layer) {
      this._layerManager.removeLayer(this.layer);
      this.layer = void 0;
    }
    if (this.layer) {
      throw new Error("AG Charts - unable to deregister scene rendering layer!");
    }
    super._setLayerManager(scene);
    if (scene && ((_a = this.opts) == null ? void 0 : _a.layer)) {
      const { zIndex, zIndexSubOrder, name } = (_b = this.opts) != null ? _b : {};
      const getComputedOpacity = () => this.getComputedOpacity();
      const getVisibility = () => this.getVisibility();
      this.layer = scene.addLayer({
        zIndex,
        zIndexSubOrder,
        name,
        getComputedOpacity,
        getVisibility
      });
    }
  }
  getComputedOpacity() {
    let opacity = 1;
    let node = this;
    do {
      if (node instanceof _Group2) {
        opacity *= node.opacity;
      }
    } while (node = node.parent);
    return opacity;
  }
  getVisibility() {
    let node = this;
    let visible = this.visible;
    while (node = node.parent) {
      if (node.visible) {
        continue;
      }
      visible = node.visible;
    }
    return visible;
  }
  visibilityChanged() {
    if (this.layer) {
      this.layer.enabled = this.visible;
    }
  }
  markDirty(source, type = 1) {
    if (this.isVirtual) {
      super.markDirty(source, type);
      return;
    }
    let parentType = type;
    if (type < 2 || this.layer != null) {
      parentType = 1;
    }
    super.markDirty(source, type, parentType);
  }
  // We consider a group to be boundless, thus any point belongs to it.
  containsPoint(_x, _y) {
    return true;
  }
  computeBBox() {
    this.computeTransformMatrix();
    return _Group2.computeBBox(this.children);
  }
  computeTransformedBBox() {
    return this.computeBBox();
  }
  render(renderCtx) {
    var _a, _b;
    const { opts: { name = void 0 } = {}, _debug: debug2 = () => {
    } } = this;
    const { dirty, dirtyZIndex, layer, children, clipRect, dirtyTransform } = this;
    let { ctx, forceRender, clipBBox } = renderCtx;
    const { resized, stats } = renderCtx;
    const canvasCtxTransform = ctx.getTransform();
    const isDirty = dirty >= 2 || dirtyZIndex || resized;
    let isChildDirty = isDirty;
    let isChildLayerDirty = false;
    for (const child of children) {
      isChildDirty || (isChildDirty = child.layerManager == null && child.dirty >= 1);
      isChildLayerDirty || (isChildLayerDirty = child.layerManager != null && child.dirty >= 1);
      if (isChildDirty) {
        break;
      }
    }
    if (name) {
      debug2({ name, group: this, isDirty, isChildDirty, dirtyTransform, renderCtx, forceRender });
    }
    if (dirtyTransform) {
      forceRender = "dirtyTransform";
    } else if (layer) {
      const currentBBox = this.computeBBox();
      if (this.lastBBox === void 0 || !this.lastBBox.equals(currentBBox)) {
        forceRender = "dirtyTransform";
        this.lastBBox = currentBBox;
      }
    }
    if (!isDirty && !isChildDirty && !isChildLayerDirty && !forceRender) {
      if (name && stats) {
        debug2({ name, result: "skipping", renderCtx, counts: this.nodeCount, group: this });
      }
      if (layer && stats) {
        stats.layersSkipped++;
        stats.nodesSkipped += this.nodeCount.count;
      }
      this.markClean({ recursive: false });
      return;
    }
    const groupVisible = this.visible;
    if (layer) {
      ctx = layer.context;
      ctx.save();
      ctx.resetTransform();
      if (forceRender !== "dirtyTransform") {
        forceRender = isChildDirty || dirtyZIndex;
      }
      if (forceRender)
        layer.clear();
      if (clipBBox) {
        const { width, height, x, y } = clipBBox;
        debug2(() => ({
          name,
          clipBBox,
          ctxTransform: ctx.getTransform(),
          renderCtx,
          group: this
        }));
        this.clipCtx(ctx, x, y, width, height);
      }
      ctx.setTransform(canvasCtxTransform);
    } else {
      ctx.globalAlpha *= this.opacity;
    }
    this.computeTransformMatrix();
    this.matrix.toContext(ctx);
    if (clipRect) {
      const { x, y, width, height } = clipRect;
      ctx.save();
      debug2(() => ({ name, clipRect, ctxTransform: ctx.getTransform(), renderCtx, group: this }));
      this.clipCtx(ctx, x, y, width, height);
      clipBBox = this.matrix.transformBBox(clipRect);
    }
    const hasVirtualChildren = this.hasVirtualChildren();
    if (dirtyZIndex) {
      this.sortChildren(children);
      if (forceRender !== "dirtyTransform")
        forceRender = true;
    } else if (hasVirtualChildren) {
      this.sortChildren(children);
    }
    const renderContextChanged = forceRender !== renderCtx.forceRender || clipBBox !== renderCtx.clipBBox || ctx !== renderCtx.ctx;
    const childRenderContext = renderContextChanged ? __spreadProps(__spreadValues({}, renderCtx), { ctx, forceRender, clipBBox }) : renderCtx;
    let skipped = 0;
    for (const child of children) {
      if (!child.visible || !groupVisible) {
        child.markClean();
        if (stats)
          skipped += child.nodeCount.count;
        continue;
      }
      if (!forceRender && child.dirty === 0) {
        if (stats)
          skipped += child.nodeCount.count;
        continue;
      }
      ctx.save();
      child.render(childRenderContext);
      ctx.restore();
    }
    if (stats)
      stats.nodesSkipped += skipped;
    super.render(renderCtx);
    if (clipRect) {
      ctx.restore();
    }
    if (hasVirtualChildren) {
      for (const child of this.virtualChildren) {
        child.markClean({ recursive: "virtual" });
      }
    }
    if (layer) {
      if (stats)
        stats.layersRendered++;
      ctx.restore();
      if (forceRender)
        layer.snapshot();
      (_b = (_a = layer.context).verifyDepthZero) == null ? void 0 : _b.call(_a);
    }
    if (name && stats) {
      debug2({ name, result: "rendered", skipped, renderCtx, counts: this.nodeCount, group: this });
    }
  }
  sortChildren(children) {
    this.dirtyZIndex = false;
    children.sort((a, b) => {
      var _a, _b;
      return compoundAscending(
        [a.zIndex, ...(_a = a.zIndexSubOrder) != null ? _a : [void 0, void 0], a.serialNumber],
        [b.zIndex, ...(_b = b.zIndexSubOrder) != null ? _b : [void 0, void 0], b.serialNumber],
        ascendingStringNumberUndefined
      );
    });
  }
  clipCtx(ctx, x, y, width, height) {
    ctx.beginPath();
    ctx.moveTo(x, y);
    ctx.lineTo(x + width, y);
    ctx.lineTo(x + width, y + height);
    ctx.lineTo(x, y + height);
    ctx.closePath();
    ctx.clip();
  }
  static computeBBox(nodes) {
    let left = Infinity;
    let right = -Infinity;
    let top = Infinity;
    let bottom = -Infinity;
    nodes.forEach((n) => {
      if (!n.visible) {
        return;
      }
      const bbox = n.computeTransformedBBox();
      if (!bbox) {
        return;
      }
      const x = bbox.x;
      const y = bbox.y;
      if (x < left) {
        left = x;
      }
      if (y < top) {
        top = y;
      }
      if (x + bbox.width > right) {
        right = x + bbox.width;
      }
      if (y + bbox.height > bottom) {
        bottom = y + bbox.height;
      }
    });
    return new BBox(left, top, right - left, bottom - top);
  }
  /**
   * Transforms bbox given in the canvas coordinate space to bbox in this group's coordinate space and
   * sets this group's clipRect to the transformed bbox.
   * @param bbox clipRect bbox in the canvas coordinate space.
   */
  setClipRectInGroupCoordinateSpace(bbox) {
    this.clipRect = bbox ? this.transformBBox(bbox) : void 0;
  }
};
_Group.className = "Group";
__decorateClass([
  SceneChangeDetection({
    redraw: 3,
    convertor: (v) => Math.min(1, Math.max(0, v))
  })
], _Group.prototype, "opacity", 2);
var Group = _Group;
var Range = class extends Shape {
  constructor(opts = {}) {
    super(opts);
    this.x1 = 0;
    this.y1 = 0;
    this.x2 = 0;
    this.y2 = 0;
    this.startLine = false;
    this.endLine = false;
    this.isRange = false;
    this.restoreOwnStyles();
  }
  computeBBox() {
    return new BBox(this.x1, this.y1, this.x2 - this.x1, this.y2 - this.y1);
  }
  isPointInPath(_x, _y) {
    return false;
  }
  render(renderCtx) {
    var _a;
    const { ctx, forceRender, stats } = renderCtx;
    if (this.dirty === 0 && !forceRender) {
      if (stats)
        stats.nodesSkipped += this.nodeCount.count;
      return;
    }
    this.computeTransformMatrix();
    this.matrix.toContext(ctx);
    let { x1, y1, x2, y2 } = this;
    x1 = this.align(x1);
    y1 = this.align(y1);
    x2 = this.align(x2);
    y2 = this.align(y2);
    const { fill, opacity, isRange } = this;
    const fillActive = !!(isRange && fill);
    if (fillActive) {
      const { fillOpacity } = this;
      ctx.fillStyle = fill;
      ctx.globalAlpha = opacity * fillOpacity;
      ctx.beginPath();
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y1);
      ctx.lineTo(x2, y2);
      ctx.lineTo(x1, y2);
      ctx.closePath();
      ctx.fill();
    }
    const { stroke, strokeWidth, startLine, endLine } = this;
    const strokeActive = !!((startLine || endLine) && stroke && strokeWidth);
    if (strokeActive) {
      const { strokeOpacity, lineDash, lineDashOffset, lineCap, lineJoin } = this;
      ctx.strokeStyle = stroke;
      ctx.globalAlpha = opacity * strokeOpacity;
      ctx.lineWidth = strokeWidth;
      if (lineDash) {
        ctx.setLineDash(lineDash);
      }
      if (lineDashOffset) {
        ctx.lineDashOffset = lineDashOffset;
      }
      if (lineCap) {
        ctx.lineCap = lineCap;
      }
      if (lineJoin) {
        ctx.lineJoin = lineJoin;
      }
      ctx.beginPath();
      if (startLine) {
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y1);
      }
      if (endLine) {
        ctx.moveTo(x2, y2);
        ctx.lineTo(x1, y2);
      }
      ctx.stroke();
    }
    (_a = this.fillShadow) == null ? void 0 : _a.markClean();
    super.render(renderCtx);
  }
};
Range.className = "Range";
Range.defaultStyles = __spreadProps(__spreadValues({}, Shape.defaultStyles), {
  strokeWidth: 1
});
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], Range.prototype, "x1", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], Range.prototype, "y1", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], Range.prototype, "x2", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], Range.prototype, "y2", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], Range.prototype, "startLine", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], Range.prototype, "endLine", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 2
    /* MINOR */
  })
], Range.prototype, "isRange", 2);
var Label = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.color = "#464646";
    this.fontSize = 12;
    this.fontFamily = "Verdana, sans-serif";
  }
  getFont() {
    return getFont(this);
  }
};
__decorateClass([
  Validate(BOOLEAN)
], Label.prototype, "enabled", 2);
__decorateClass([
  Validate(COLOR_STRING)
], Label.prototype, "color", 2);
__decorateClass([
  Validate(FONT_STYLE, { optional: true })
], Label.prototype, "fontStyle", 2);
__decorateClass([
  Validate(FONT_WEIGHT, { optional: true })
], Label.prototype, "fontWeight", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], Label.prototype, "fontSize", 2);
__decorateClass([
  Validate(STRING)
], Label.prototype, "fontFamily", 2);
__decorateClass([
  Validate(FUNCTION, { optional: true })
], Label.prototype, "formatter", 2);
function calculateLabelRotation(opts) {
  const { parallelFlipRotation = 0, regularFlipRotation = 0 } = opts;
  const configuredRotation = opts.rotation ? normalizeAngle360(toRadians(opts.rotation)) : 0;
  const parallelFlipFlag = !configuredRotation && parallelFlipRotation >= 0 && parallelFlipRotation <= Math.PI ? -1 : 1;
  const regularFlipFlag = !configuredRotation && regularFlipRotation >= 0 && regularFlipRotation <= Math.PI ? -1 : 1;
  let defaultRotation = 0;
  if (opts.parallel) {
    defaultRotation = parallelFlipFlag * Math.PI / 2;
  } else if (regularFlipFlag === -1) {
    defaultRotation = Math.PI;
  }
  return { configuredRotation, defaultRotation, parallelFlipFlag, regularFlipFlag };
}
function getLabelSpacing(minSpacing, rotated) {
  if (!isNaN(minSpacing)) {
    return minSpacing;
  }
  return rotated ? 0 : 10;
}
function getTextBaseline(parallel, labelRotation, sideFlag, parallelFlipFlag) {
  if (parallel && !labelRotation) {
    return sideFlag * parallelFlipFlag === -1 ? "hanging" : "bottom";
  }
  return "middle";
}
function getTextAlign(parallel, labelRotation, labelAutoRotation, sideFlag, regularFlipFlag) {
  const labelRotated = labelRotation > 0 && labelRotation <= Math.PI;
  const labelAutoRotated = labelAutoRotation > 0 && labelAutoRotation <= Math.PI;
  const alignFlag = labelRotated || labelAutoRotated ? -1 : 1;
  if (parallel) {
    if (labelRotation || labelAutoRotation) {
      if (sideFlag * alignFlag === -1) {
        return "end";
      }
    } else {
      return "center";
    }
  } else if (sideFlag * regularFlipFlag === -1) {
    return "end";
  }
  return "start";
}
function calculateLabelBBox(text, bbox, labelX, labelY, labelMatrix) {
  const { width, height } = bbox;
  const translatedBBox = new BBox(labelX, labelY, 0, 0);
  labelMatrix.transformBBox(translatedBBox, bbox);
  const { x = 0, y = 0 } = bbox;
  bbox.width = width;
  bbox.height = height;
  return {
    point: { x, y, size: 0 },
    label: { width, height, text }
  };
}
var Layers = /* @__PURE__ */ ((Layers2) => {
  Layers2[Layers2["SERIES_BACKGROUND_ZINDEX"] = 0] = "SERIES_BACKGROUND_ZINDEX";
  Layers2[Layers2["AXIS_GRID_ZINDEX"] = 1] = "AXIS_GRID_ZINDEX";
  Layers2[Layers2["AXIS_ZINDEX"] = 2] = "AXIS_ZINDEX";
  Layers2[Layers2["SERIES_CROSSLINE_RANGE_ZINDEX"] = 3] = "SERIES_CROSSLINE_RANGE_ZINDEX";
  Layers2[Layers2["SERIES_LAYER_ZINDEX"] = 4] = "SERIES_LAYER_ZINDEX";
  Layers2[Layers2["AXIS_FOREGROUND_ZINDEX"] = 5] = "AXIS_FOREGROUND_ZINDEX";
  Layers2[Layers2["SERIES_CROSSHAIR_ZINDEX"] = 6] = "SERIES_CROSSHAIR_ZINDEX";
  Layers2[Layers2["SERIES_LABEL_ZINDEX"] = 7] = "SERIES_LABEL_ZINDEX";
  Layers2[Layers2["SERIES_CROSSLINE_LINE_ZINDEX"] = 8] = "SERIES_CROSSLINE_LINE_ZINDEX";
  Layers2[Layers2["LEGEND_ZINDEX"] = 9] = "LEGEND_ZINDEX";
  return Layers2;
})(Layers || {});
var integrated_charts_scene_exports = {};
__export(integrated_charts_scene_exports, {
  Arc: () => Arc,
  BBox: () => BBox,
  BandScale: () => BandScale,
  Caption: () => Caption,
  Circle: () => Circle,
  ContinuousScale: () => ContinuousScale,
  Diamond: () => Diamond,
  DropShadow: () => DropShadow,
  Group: () => Group,
  HdpiCanvas: () => HdpiCanvas,
  Image: () => Image,
  Label: () => Label,
  Line: () => Line,
  LinearGradientFill: () => LinearGradientFill,
  LinearScale: () => LinearScale,
  Marker: () => Marker,
  Node: () => Node,
  Path: () => Path,
  Path2D: () => Path2D,
  PointerEvents: () => PointerEvents,
  Rect: () => Rect,
  RedrawType: () => RedrawType,
  Scene: () => Scene,
  SceneChangeDetection: () => SceneChangeDetection,
  ScenePathChangeDetection: () => ScenePathChangeDetection,
  Sector: () => Sector,
  Selection: () => Selection,
  Shape: () => Shape,
  Square: () => Square,
  Text: () => Text,
  Tooltip: () => Tooltip,
  Triangle: () => Triangle,
  easing: () => easing_exports,
  getFont: () => getFont,
  getMarker: () => getMarker,
  motion: () => motion,
  nearestSquared: () => nearestSquared,
  nearestSquaredInContainer: () => nearestSquaredInContainer,
  toRadians: () => toRadians,
  toTooltipHtml: () => toTooltipHtml
});
var fromToMotion_exports = {};
__export(fromToMotion_exports, {
  FROM_TO_MIXINS: () => FROM_TO_MIXINS,
  NODE_UPDATE_PHASES: () => NODE_UPDATE_PHASES,
  fromToMotion: () => fromToMotion,
  staticFromToMotion: () => staticFromToMotion
});
function zipObject(keys, values) {
  const zipped = {};
  if (Array.isArray(values)) {
    for (let i = 0; i < keys.length; i++) {
      zipped[`${keys[i]}`] = values[i];
    }
  } else {
    for (let i = 0; i < keys.length; i++) {
      zipped[`${keys[i]}`] = values;
    }
  }
  return zipped;
}
function interpolateNumber(a, b) {
  return (d) => Number(a) * (1 - d) + Number(b) * d;
}
function interpolateColor(a, b) {
  if (typeof a === "string") {
    try {
      a = Color.fromString(a);
    } catch (e) {
      a = Color.fromArray([0, 0, 0]);
    }
  }
  if (typeof b === "string") {
    try {
      b = Color.fromString(b);
    } catch (e) {
      b = Color.fromArray([0, 0, 0]);
    }
  }
  const red = interpolateNumber(a.r, b.r);
  const green = interpolateNumber(a.g, b.g);
  const blue = interpolateNumber(a.b, b.b);
  const alpha = interpolateNumber(a.a, b.a);
  return (d) => Color.fromArray([red(d), green(d), blue(d), alpha(d)]).toRgbaString();
}
var easing_exports = {};
__export(easing_exports, {
  easeIn: () => easeIn,
  easeInOut: () => easeInOut,
  easeInOutQuad: () => easeInOutQuad,
  easeInQuad: () => easeInQuad,
  easeOut: () => easeOut,
  easeOutQuad: () => easeOutQuad,
  inverseEaseOut: () => inverseEaseOut,
  linear: () => linear
});
var linear = (n) => n;
var easeIn = (n) => 1 - Math.cos(n * Math.PI / 2);
var easeOut = (n) => Math.sin(n * Math.PI / 2);
var easeInOut = (n) => -(Math.cos(n * Math.PI) - 1) / 2;
var easeInQuad = (n) => n * n;
var easeOutQuad = (n) => 1 - __pow(1 - n, 2);
var easeInOutQuad = (n) => n < 0.5 ? 2 * n * n : 1 - __pow(-2 * n + 2, 2) / 2;
var inverseEaseOut = (x) => 2 * Math.asin(x) / Math.PI;
var QUICK_TRANSITION = 0.2;
var INITIAL_LOAD = {
  animationDuration: 1,
  animationDelay: 0
};
var REMOVE_PHASE = {
  animationDuration: 0.25,
  animationDelay: 0
};
var UPDATE_PHASE = {
  animationDuration: 0.5,
  animationDelay: 0.25
};
var ADD_PHASE = {
  animationDuration: 0.25,
  animationDelay: 0.75
};
var LABEL_PHASE = {
  animationDuration: QUICK_TRANSITION,
  animationDelay: 1
};
var RepeatType = /* @__PURE__ */ ((RepeatType2) => {
  RepeatType2["Loop"] = "loop";
  RepeatType2["Reverse"] = "reverse";
  return RepeatType2;
})(RepeatType || {});
function isNodeArray(array) {
  return array.every((n) => n instanceof Node);
}
function deconstructSelectionsOrNodes(selectionsOrNodes) {
  return isNodeArray(selectionsOrNodes) ? { nodes: selectionsOrNodes, selections: [] } : { nodes: [], selections: selectionsOrNodes };
}
var Animation = class {
  constructor(opts) {
    this.elapsed = 0;
    this.iteration = 0;
    this.isPlaying = false;
    this.isReverse = false;
    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
    this.id = opts.id;
    this.groupId = opts.groupId;
    this.autoplay = (_a = opts.autoplay) != null ? _a : true;
    this.delay = (_b = opts.delay) != null ? _b : 0;
    this.duration = (_c = opts.duration) != null ? _c : 1e3;
    this.ease = (_d = opts.ease) != null ? _d : linear;
    this.repeat = (_e = opts.repeat) != null ? _e : 0;
    this.repeatType = (_f = opts.repeatType) != null ? _f : "loop";
    this.onComplete = opts.onComplete;
    this.onPlay = opts.onPlay;
    this.onStop = opts.onStop;
    this.onRepeat = opts.onRepeat;
    this.onUpdate = opts.onUpdate;
    this.interpolate = this.createInterpolator(opts.from, opts.to);
    if (opts.skip === true) {
      (_g = this.onUpdate) == null ? void 0 : _g.call(this, opts.to, false, this);
      (_h = this.onStop) == null ? void 0 : _h.call(this, this);
      (_i = this.onComplete) == null ? void 0 : _i.call(this, this);
    } else if (this.autoplay) {
      this.play();
      (_j = this.onUpdate) == null ? void 0 : _j.call(this, opts.from, true, this);
    }
  }
  play() {
    var _a;
    if (!this.isPlaying) {
      this.isPlaying = true;
      (_a = this.onPlay) == null ? void 0 : _a.call(this, this);
    }
    return this;
  }
  pause() {
    if (this.isPlaying) {
      this.isPlaying = false;
    }
    return this;
  }
  stop() {
    var _a;
    if (this.isPlaying) {
      this.isPlaying = false;
      (_a = this.onStop) == null ? void 0 : _a.call(this, this);
    }
    return this;
  }
  reset(opts) {
    const deltaState = this.interpolate(this.isReverse ? 1 - this.delta : this.delta);
    this.interpolate = this.createInterpolator(deltaState, opts.to);
    this.elapsed = 0;
    this.iteration = 0;
    if (typeof opts.delay === "number") {
      this.delay = opts.delay;
    }
    if (typeof opts.duration === "number") {
      this.duration = opts.duration;
    }
    if (typeof opts.ease === "function") {
      this.ease = opts.ease;
    }
    return this;
  }
  update(time) {
    var _a, _b, _c;
    this.elapsed += time;
    if (this.elapsed <= this.delay) {
      return this;
    }
    const value = this.interpolate(this.isReverse ? 1 - this.delta : this.delta);
    (_a = this.onUpdate) == null ? void 0 : _a.call(this, value, false, this);
    if (this.elapsed - this.delay >= this.duration) {
      if (this.iteration < this.repeat) {
        this.iteration++;
        this.elapsed = (this.elapsed - this.delay) % this.duration + this.delay;
        if (this.repeatType === "reverse") {
          this.isReverse = !this.isReverse;
        }
        (_b = this.onRepeat) == null ? void 0 : _b.call(this, this);
      } else {
        this.stop();
        (_c = this.onComplete) == null ? void 0 : _c.call(this, this);
      }
    }
    return this;
  }
  get delta() {
    return this.ease(clamp2(0, (this.elapsed - this.delay) / this.duration, 1));
  }
  createInterpolator(from, to) {
    if (typeof to !== "object") {
      return this.interpolateValue(from, to);
    }
    const interpolatorEntries = [];
    for (const key in to) {
      const interpolator = this.interpolateValue(from[key], to[key]);
      if (interpolator != null) {
        interpolatorEntries.push([key, interpolator]);
      }
    }
    return (d) => {
      const result = {};
      for (const [key, interpolator] of interpolatorEntries) {
        result[key] = interpolator(d);
      }
      return result;
    };
  }
  interpolateValue(a, b) {
    if (a === void 0 || b === void 0) {
      return void 0;
    }
    try {
      switch (typeof a) {
        case "number":
          return interpolateNumber(a, b);
        case "string":
          return interpolateColor(a, b);
      }
    } catch (e) {
    }
    throw new Error(`Unable to interpolate values: ${a}, ${b}`);
  }
};
var NODE_UPDATE_PHASES = ["removed", "updated", "added"];
var FROM_TO_MIXINS = {
  added: ADD_PHASE,
  updated: UPDATE_PHASE,
  removed: REMOVE_PHASE,
  unknown: INITIAL_LOAD
};
function fromToMotion(groupId, subId, animationManager, selectionsOrNodes, fns, getDatumId, diff2) {
  const { defaultDuration } = animationManager;
  const { fromFn, toFn, intermediateFn } = fns;
  const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes);
  const ids = { added: {}, removed: {} };
  if (getDatumId && diff2) {
    ids.added = zipObject(diff2.added, true);
    ids.removed = zipObject(diff2.removed, true);
  }
  const processNodes = (liveNodes, nodes2) => {
    var _c, _d;
    let prevFromProps;
    let liveNodeIndex = 0;
    let nodeIndex = 0;
    for (const node of nodes2) {
      const isLive = liveNodes[liveNodeIndex] === node;
      const ctx = {
        last: nodeIndex >= nodes2.length - 1,
        lastLive: liveNodeIndex >= liveNodes.length - 1,
        prev: nodes2[nodeIndex - 1],
        prevFromProps,
        prevLive: liveNodes[liveNodeIndex - 1],
        next: nodes2[nodeIndex + 1],
        nextLive: liveNodes[liveNodeIndex + (isLive ? 1 : 0)]
      };
      const animationId = `${groupId}_${subId}_${node.id}`;
      animationManager.stopByAnimationId(animationId);
      let status = "unknown";
      if (!isLive) {
        status = "removed";
      } else if (getDatumId && diff2) {
        status = calculateStatus(node, node.datum, getDatumId, ids);
      }
      const _a = fromFn(node, node.datum, status, ctx), {
        animationDelay: delay,
        animationDuration: duration,
        start = {},
        finish = {}
      } = _a, from = __objRest(_a, [
        "animationDelay",
        "animationDuration",
        "start",
        "finish"
      ]);
      const _b = toFn(node, node.datum, status, ctx), {
        animationDelay: toDelay,
        animationDuration: toDuration,
        start: toStart = {},
        finish: toFinish = {}
      } = _b, to = __objRest(_b, [
        "animationDelay",
        "animationDuration",
        "start",
        "finish"
      ]);
      animationManager.animate({
        id: animationId,
        groupId,
        from,
        to,
        ease: easeOut,
        onPlay: () => {
          node.setProperties(__spreadValues(__spreadValues({}, start), toStart));
        },
        onUpdate(props) {
          node.setProperties(props);
          if (intermediateFn) {
            node.setProperties(intermediateFn(node, node.datum, status, ctx));
          }
        },
        onStop: () => {
          node.setProperties(__spreadValues(__spreadValues(__spreadValues({}, to), finish), toFinish));
        },
        duration: ((_c = duration != null ? duration : toDuration) != null ? _c : 1) * defaultDuration,
        delay: ((_d = delay != null ? delay : toDelay) != null ? _d : 0) * defaultDuration
      });
      if (isLive) {
        liveNodeIndex++;
      }
      nodeIndex++;
      prevFromProps = from;
    }
  };
  let selectionIndex = 0;
  for (const selection of selections) {
    const nodes2 = selection.nodes();
    const liveNodes = nodes2.filter((n) => !selection.isGarbage(n));
    processNodes(liveNodes, nodes2);
    animationManager.animate({
      id: `${groupId}_${subId}_selection_${selectionIndex}`,
      groupId,
      from: 0,
      to: 1,
      ease: easeOut,
      onStop() {
        selection.cleanup();
      }
    });
    selectionIndex++;
  }
  processNodes(nodes, nodes);
}
function staticFromToMotion(groupId, subId, animationManager, selectionsOrNodes, from, to, extraOpts = {}) {
  const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes);
  const { animationDelay = 0, animationDuration = 1, start = {}, finish = {} } = extraOpts;
  const { defaultDuration } = animationManager;
  animationManager.animate({
    id: `${groupId}_${subId}`,
    groupId,
    from,
    to,
    ease: easeOut,
    onPlay: () => {
      for (const node of nodes) {
        node.setProperties(start);
      }
      for (const selection of selections) {
        for (const node of selection.nodes()) {
          node.setProperties(start);
        }
      }
    },
    onUpdate(props) {
      for (const node of nodes) {
        node.setProperties(props);
      }
      for (const selection of selections) {
        for (const node of selection.nodes()) {
          node.setProperties(props);
        }
      }
    },
    onStop: () => {
      for (const node of nodes) {
        node.setProperties(__spreadValues(__spreadValues({}, to), finish));
      }
      for (const selection of selections) {
        for (const node of selection.nodes()) {
          node.setProperties(__spreadValues(__spreadValues({}, to), finish));
        }
      }
    },
    duration: animationDuration * defaultDuration,
    delay: animationDelay * defaultDuration
  });
}
function calculateStatus(node, datum, getDatumId, ids) {
  const id = getDatumId(node, datum);
  if (ids.added[id]) {
    return "added";
  } else if (ids.removed[id]) {
    return "removed";
  }
  return "updated";
}
var resetMotion_exports = {};
__export(resetMotion_exports, {
  resetMotion: () => resetMotion
});
function resetMotion(selectionsOrNodes, propsFn) {
  const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes);
  for (const selection of selections) {
    for (const node of selection.nodes()) {
      const from = propsFn(node, node.datum);
      node.setProperties(from);
    }
    selection.cleanup();
  }
  for (const node of nodes) {
    const from = propsFn(node, node.datum);
    node.setProperties(from);
  }
}
var DropShadow = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.color = "rgba(0, 0, 0, 0.5)";
    this.xOffset = 0;
    this.yOffset = 0;
    this.blur = 5;
  }
};
__decorateClass([
  Validate(BOOLEAN),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], DropShadow.prototype, "enabled", 2);
__decorateClass([
  Validate(COLOR_STRING),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], DropShadow.prototype, "color", 2);
__decorateClass([
  Validate(NUMBER),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], DropShadow.prototype, "xOffset", 2);
__decorateClass([
  Validate(NUMBER),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], DropShadow.prototype, "yOffset", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], DropShadow.prototype, "blur", 2);
var HdpiOffscreenCanvas = class {
  // The width/height attributes of the Canvas element default to
  // 300/150 according to w3.org.
  constructor({ width = 600, height = 300, overrideDevicePixelRatio }) {
    this.enabled = true;
    this._pixelRatio = NaN;
    this._width = 0;
    this._height = 0;
    this.canvas = new OffscreenCanvas(width, height);
    this.realContext = this.canvas.getContext("2d");
    this.imageSource = this.canvas.transferToImageBitmap();
    this.context = this.setPixelRatio(overrideDevicePixelRatio);
    this.resize(width, height);
  }
  static isSupported() {
    return typeof OffscreenCanvas !== "undefined" && OffscreenCanvas.prototype.transferToImageBitmap != null;
  }
  snapshot() {
    this.imageSource.close();
    this.imageSource = this.canvas.transferToImageBitmap();
  }
  destroy() {
    this.imageSource.close();
    this.canvas.width = 0;
    this.canvas.height = 0;
    this.context.clearRect(0, 0, 0, 0);
  }
  clear() {
    this.context.save();
    this.context.resetTransform();
    this.context.clearRect(0, 0, this.width, this.height);
    this.context.restore();
  }
  get pixelRatio() {
    return this._pixelRatio;
  }
  /**
   * Changes the pixel ratio of the Canvas element to the given value,
   * or uses the window.devicePixelRatio (default), then resizes the Canvas
   * element accordingly (default).
   */
  setPixelRatio(ratio) {
    let pixelRatio = ratio != null ? ratio : window.devicePixelRatio;
    if (hasConstrainedCanvasMemory()) {
      pixelRatio = 1;
    }
    this._pixelRatio = pixelRatio;
    return HdpiCanvas.overrideScale(this.realContext, pixelRatio);
  }
  get width() {
    return this._width;
  }
  get height() {
    return this._height;
  }
  resize(width, height) {
    if (!(width > 0 && height > 0)) {
      return;
    }
    const { canvas, context, pixelRatio } = this;
    canvas.width = Math.round(width * pixelRatio);
    canvas.height = Math.round(height * pixelRatio);
    context.resetTransform();
    this._width = width;
    this._height = height;
  }
};
var advancedCompositeIdentifier = "adv-composite";
var domCompositeIdentifier = "dom-composite";
var Scene = class {
  constructor(opts) {
    this.id = createId(this);
    this.layers = [];
    this._nextZIndex = 0;
    this._nextLayerId = 0;
    this._dirty = false;
    this._root = null;
    this.debug = Debug.create(
      true,
      "scene"
      /* SCENE */
    );
    var _a;
    const {
      document: document2,
      window: window2,
      mode = (_a = windowValue("agChartsSceneRenderModel")) != null ? _a : advancedCompositeIdentifier,
      width,
      height,
      overrideDevicePixelRatio = void 0
    } = opts;
    this.overrideDevicePixelRatio = overrideDevicePixelRatio;
    this.opts = { document: document2, window: window2, mode };
    this.canvas = new HdpiCanvas({ document: document2, window: window2, width, height, overrideDevicePixelRatio });
  }
  set container(value) {
    this.canvas.container = value;
  }
  get container() {
    return this.canvas.container;
  }
  download(fileName, fileFormat) {
    this.canvas.download(fileName, fileFormat);
  }
  getDataURL(type) {
    return this.canvas.getDataURL(type);
  }
  get width() {
    return this.pendingSize ? this.pendingSize[0] : this.canvas.width;
  }
  get height() {
    return this.pendingSize ? this.pendingSize[1] : this.canvas.height;
  }
  resize(width, height) {
    width = Math.round(width);
    height = Math.round(height);
    const lessThanZero = width <= 0 || height <= 0;
    const nan = isNaN(width) || isNaN(height);
    const unchanged = width === this.width && height === this.height;
    if (unchanged || nan || lessThanZero) {
      return false;
    }
    this.pendingSize = [width, height];
    this.markDirty();
    return true;
  }
  addLayer(opts) {
    var _a;
    const { mode } = this.opts;
    const layeredModes = ["composite", domCompositeIdentifier, advancedCompositeIdentifier];
    if (!layeredModes.includes(mode)) {
      return void 0;
    }
    const { zIndex = this._nextZIndex++, name, zIndexSubOrder, getComputedOpacity, getVisibility } = opts;
    const { width, height, overrideDevicePixelRatio } = this;
    const domLayer = mode === domCompositeIdentifier;
    const advLayer = mode === advancedCompositeIdentifier;
    const canvas = !advLayer || !HdpiOffscreenCanvas.isSupported() ? new HdpiCanvas({
      document: this.opts.document,
      window: this.opts.window,
      width,
      height,
      domLayer,
      zIndex,
      name,
      overrideDevicePixelRatio
    }) : new HdpiOffscreenCanvas({
      width,
      height,
      overrideDevicePixelRatio
    });
    const newLayer = {
      id: this._nextLayerId++,
      name,
      zIndex,
      zIndexSubOrder,
      canvas,
      getComputedOpacity,
      getVisibility
    };
    if (zIndex >= this._nextZIndex) {
      this._nextZIndex = zIndex + 1;
    }
    this.layers.push(newLayer);
    this.sortLayers();
    if (domLayer) {
      const domCanvases = this.layers.map((v) => v.canvas).filter((v) => v instanceof HdpiCanvas);
      const newLayerIndex = domCanvases.findIndex((v) => v === canvas);
      const lastLayer = (_a = domCanvases[newLayerIndex - 1]) != null ? _a : this.canvas;
      lastLayer.element.insertAdjacentElement("afterend", canvas.element);
    }
    this.debug("Scene.addLayer() - layers", this.layers);
    return newLayer.canvas;
  }
  removeLayer(canvas) {
    const index = this.layers.findIndex((l) => l.canvas === canvas);
    if (index >= 0) {
      this.layers.splice(index, 1);
      canvas.destroy();
      this.markDirty();
      this.debug("Scene.removeLayer() -  layers", this.layers);
    }
  }
  moveLayer(canvas, newZIndex, newZIndexSubOrder) {
    const layer = this.layers.find((l) => l.canvas === canvas);
    if (layer) {
      layer.zIndex = newZIndex;
      layer.zIndexSubOrder = newZIndexSubOrder;
      this.sortLayers();
      this.markDirty();
      this.debug("Scene.moveLayer() -  layers", this.layers);
    }
  }
  sortLayers() {
    this.layers.sort((a, b) => {
      var _a, _b;
      return compoundAscending(
        [a.zIndex, ...(_a = a.zIndexSubOrder) != null ? _a : [void 0, void 0], a.id],
        [b.zIndex, ...(_b = b.zIndexSubOrder) != null ? _b : [void 0, void 0], b.id],
        ascendingStringNumberUndefined
      );
    });
  }
  markDirty() {
    this._dirty = true;
  }
  get dirty() {
    return this._dirty;
  }
  set root(node) {
    var _a;
    if (node === this._root) {
      return;
    }
    (_a = this._root) == null ? void 0 : _a._setLayerManager();
    this._root = node;
    if (node) {
      node._setLayerManager({
        addLayer: (opts) => this.addLayer(opts),
        moveLayer: (...opts) => this.moveLayer(...opts),
        removeLayer: (...opts) => this.removeLayer(...opts),
        markDirty: () => this.markDirty(),
        canvas: this.canvas,
        debug: Debug.create(
          "scene"
          /* SCENE */
        )
      });
    }
    this.markDirty();
  }
  get root() {
    return this._root;
  }
  /** Alternative to destroy() that preserves re-usable resources. */
  strip() {
    const { layers } = this;
    for (const layer of layers) {
      layer.canvas.destroy();
      delete layer["canvas"];
    }
    layers.splice(0, layers.length);
    this.root = null;
    this._dirty = false;
    this.canvas.context.resetTransform();
  }
  destroy() {
    this.container = void 0;
    this.strip();
    this.canvas.destroy();
    Object.assign(this, { canvas: void 0, ctx: void 0 });
  }
  render(opts) {
    return __async(this, null, function* () {
      var _a, _b;
      const { debugSplitTimes = { start: performance.now() }, extraDebugStats = {} } = opts != null ? opts : {};
      const {
        canvas,
        canvas: { context: ctx },
        root,
        layers,
        pendingSize,
        opts: { mode }
      } = this;
      if (pendingSize) {
        this.canvas.resize(...pendingSize);
        this.layers.forEach((layer) => layer.canvas.resize(...pendingSize));
        this.pendingSize = void 0;
      }
      if (root && !root.visible) {
        this._dirty = false;
        return;
      }
      if (root && !this.dirty) {
        this.debug("Scene.render() - no-op", {
          redrawType: RedrawType[root.dirty],
          tree: this.buildTree(root)
        });
        this.debugStats(debugSplitTimes, ctx, void 0, extraDebugStats);
        return;
      }
      const renderCtx = {
        ctx,
        devicePixelRatio: (_a = this.canvas.pixelRatio) != null ? _a : 1,
        forceRender: true,
        resized: !!pendingSize,
        debugNodes: {}
      };
      if (Debug.check(
        "scene:stats:verbose"
        /* SCENE_STATS_VERBOSE */
      )) {
        renderCtx.stats = { layersRendered: 0, layersSkipped: 0, nodesRendered: 0, nodesSkipped: 0 };
      }
      let canvasCleared = false;
      if (!root || root.dirty >= 1) {
        canvasCleared = true;
        canvas.clear();
      }
      if (root) {
        const { dirtyTree, paths } = this.buildDirtyTree(root);
        Debug.create(
          "scene:dirtyTree"
          /* SCENE_DIRTY_TREE */
        )("Scene.render() - dirtyTree", {
          dirtyTree,
          paths
        });
      }
      if (root && canvasCleared) {
        this.debug("Scene.render() - before", {
          redrawType: RedrawType[root.dirty],
          canvasCleared,
          tree: this.buildTree(root)
        });
        if (root.visible) {
          ctx.save();
          root.render(renderCtx);
          ctx.restore();
        }
      }
      debugSplitTimes["\u270D\uFE0F"] = performance.now();
      if (mode !== domCompositeIdentifier && layers.length > 0 && canvasCleared) {
        this.sortLayers();
        ctx.save();
        ctx.setTransform(1 / canvas.pixelRatio, 0, 0, 1 / canvas.pixelRatio, 0, 0);
        layers.forEach(({ canvas: { imageSource, enabled }, getComputedOpacity, getVisibility }) => {
          if (!enabled || !getVisibility()) {
            return;
          }
          ctx.globalAlpha = getComputedOpacity();
          ctx.drawImage(imageSource, 0, 0);
        });
        ctx.restore();
        debugSplitTimes["\u26D9"] = performance.now();
      }
      (_b = ctx.verifyDepthZero) == null ? void 0 : _b.call(ctx);
      this._dirty = false;
      this.debugStats(debugSplitTimes, ctx, renderCtx.stats, extraDebugStats);
      this.debugSceneNodeHighlight(ctx, renderCtx.debugNodes);
      if (root) {
        this.debug("Scene.render() - after", {
          redrawType: RedrawType[root.dirty],
          canvasCleared,
          tree: this.buildTree(root)
        });
      }
    });
  }
  debugStats(debugSplitTimes, ctx, renderCtxStats, extraDebugStats = {}) {
    if (Debug.check(
      "scene:stats",
      "scene:stats:verbose"
      /* SCENE_STATS_VERBOSE */
    )) {
      const end = performance.now();
      const start = debugSplitTimes["start"];
      debugSplitTimes["end"] = performance.now();
      const pct = (rendered, skipped) => {
        const total = rendered + skipped;
        return `${rendered} / ${total} (${Math.round(100 * rendered / total)}%)`;
      };
      const time = (name, start2, end2) => {
        return `${name}: ${Math.round((end2 - start2) * 100) / 100}ms`;
      };
      const { layersRendered = 0, layersSkipped = 0, nodesRendered = 0, nodesSkipped = 0 } = renderCtxStats != null ? renderCtxStats : {};
      let lastSplit = 0;
      const splits = Object.entries(debugSplitTimes).filter(([n]) => n !== "end").map(([n, t], i) => {
        const result = i > 0 ? time(n, lastSplit, t) : null;
        lastSplit = t;
        return result;
      }).filter((v) => v != null).join(" + ");
      const extras = Object.entries(extraDebugStats).map(([k, v]) => `${k}: ${v}`).join(" ; ");
      const detailedStats = Debug.check(
        "scene:stats:verbose"
        /* SCENE_STATS_VERBOSE */
      );
      const stats = [
        `${time("\u23F1\uFE0F", start, end)} (${splits})`,
        `${extras}`,
        `Layers: ${detailedStats ? pct(layersRendered, layersSkipped) : this.layers.length}`,
        detailedStats ? `Nodes: ${pct(nodesRendered, nodesSkipped)}` : null
      ].filter((v) => v != null);
      const statsSize = stats.map((t) => [t, HdpiCanvas.getTextSize(t, ctx.font)]);
      const width = Math.max(...statsSize.map(([, { width: width2 }]) => width2));
      const height = statsSize.reduce((total, [, { height: height2 }]) => total + height2, 0);
      ctx.save();
      ctx.fillStyle = "white";
      ctx.fillRect(0, 0, width, height);
      ctx.fillStyle = "black";
      let y = 0;
      for (const [stat, size] of statsSize) {
        y += size.height;
        ctx.fillText(stat, 2, y);
      }
      ctx.restore();
    }
  }
  debugSceneNodeHighlight(ctx, debugNodes) {
    var _a;
    const regexpPredicate = (matcher) => (n) => {
      if (matcher.test(n.id)) {
        return true;
      }
      return n instanceof Group && n.name != null && matcher.test(n.name);
    };
    const stringPredicate = (match) => (n) => {
      if (match === n.id) {
        return true;
      }
      return n instanceof Group && n.name != null && match === n.name;
    };
    const sceneNodeHighlight = toArray(windowValue("agChartsSceneDebug")).flatMap(
      (name) => name === "layout" ? ["seriesRoot", "legend", "root", /.*Axis-\d+-axis.*/] : name
    );
    for (const next of sceneNodeHighlight) {
      if (typeof next === "string" && debugNodes[next] != null)
        continue;
      const predicate = typeof next === "string" ? stringPredicate(next) : regexpPredicate(next);
      const nodes = (_a = this.root) == null ? void 0 : _a.findNodes(predicate);
      if (!nodes || nodes.length === 0) {
        Logger.log(`Scene.render() - no debugging node with id [${next}] in scene graph.`);
        continue;
      }
      for (const node of nodes) {
        if (node instanceof Group && node.name) {
          debugNodes[node.name] = node;
        } else {
          debugNodes[node.id] = node;
        }
      }
    }
    ctx.save();
    for (const [name, node] of Object.entries(debugNodes)) {
      const bbox = node.computeTransformedBBox();
      if (!bbox) {
        Logger.log(`Scene.render() - no bbox for debugged node [${name}].`);
        continue;
      }
      ctx.globalAlpha = 0.8;
      ctx.strokeStyle = "red";
      ctx.lineWidth = 1;
      ctx.strokeRect(bbox.x, bbox.y, bbox.width, bbox.height);
      ctx.fillStyle = "red";
      ctx.strokeStyle = "white";
      ctx.font = "16px sans-serif";
      ctx.textBaseline = "top";
      ctx.textAlign = "left";
      ctx.lineWidth = 2;
      ctx.strokeText(name, bbox.x, bbox.y, bbox.width);
      ctx.fillText(name, bbox.x, bbox.y, bbox.width);
    }
    ctx.restore();
  }
  buildTree(node) {
    var _a, _b;
    const name = (_a = node instanceof Group ? node.name : null) != null ? _a : node.id;
    return __spreadValues(__spreadValues({
      name,
      node,
      dirty: RedrawType[node.dirty]
    }, ((_b = node.parent) == null ? void 0 : _b.isVirtual) ? {
      virtualParentDirty: RedrawType[node.parent.dirty],
      virtualParent: node.parent
    } : {}), node.children.map((c) => this.buildTree(c)).reduce((result, childTree) => {
      let { name: treeNodeName } = childTree;
      const {
        node: { visible, opacity, zIndex, zIndexSubOrder },
        node: childNode,
        virtualParent
      } = childTree;
      if (!visible || opacity <= 0) {
        treeNodeName = `(${treeNodeName})`;
      }
      if (childNode instanceof Group && childNode.isLayer()) {
        treeNodeName = `*${treeNodeName}*`;
      }
      const key = [
        `${treeNodeName != null ? treeNodeName : "<unknown>"}`,
        `z: ${zIndex}`,
        zIndexSubOrder && `zo: ${zIndexSubOrder.map((v) => typeof v === "function" ? `${v()} (fn)` : v).join(" / ")}`,
        virtualParent && `(virtual parent)`
      ].filter((v) => !!v).join(" ");
      let selectedKey = key;
      let index = 1;
      while (result[selectedKey] != null && index < 100) {
        selectedKey = `${key} (${index++})`;
      }
      result[selectedKey] = childTree;
      return result;
    }, {}));
  }
  buildDirtyTree(node) {
    var _a;
    if (node.dirty === 0) {
      return { dirtyTree: {}, paths: [] };
    }
    const childrenDirtyTree = node.children.map((c) => this.buildDirtyTree(c)).filter((c) => c.paths.length > 0);
    const name = (_a = node instanceof Group ? node.name : null) != null ? _a : node.id;
    const paths = childrenDirtyTree.length === 0 ? [name] : childrenDirtyTree.map((c) => c.paths).reduce((r, p) => r.concat(p), []).map((p) => `${name}.${p}`);
    return {
      dirtyTree: __spreadValues({
        name,
        node,
        dirty: RedrawType[node.dirty]
      }, childrenDirtyTree.map((c) => c.dirtyTree).filter((t) => t.dirty !== void 0).reduce((result, childTree) => {
        var _a2;
        result[(_a2 = childTree.name) != null ? _a2 : "<unknown>"] = childTree;
        return result;
      }, {})),
      paths
    };
  }
};
Scene.className = "Scene";
var Selection = class _Selection {
  constructor(parentNode, classOrFactory, autoCleanup = true) {
    this.parentNode = parentNode;
    this.autoCleanup = autoCleanup;
    this.garbageBin = /* @__PURE__ */ new Set();
    this._nodesMap = /* @__PURE__ */ new Map();
    this._nodes = [];
    this.data = [];
    this.debug = Debug.create(true, "scene", "scene:selections");
    this.nodeFactory = Object.prototype.isPrototypeOf.call(Node, classOrFactory) ? () => new classOrFactory() : classOrFactory;
  }
  static select(parent, classOrFactory, garbageCollection = true) {
    return new _Selection(parent, classOrFactory, garbageCollection);
  }
  static selectAll(parent, predicate) {
    const results = [];
    const traverse = (node) => {
      if (predicate(node)) {
        results.push(node);
      }
      node.children.forEach(traverse);
    };
    traverse(parent);
    return results;
  }
  static selectByClass(node, Class) {
    return _Selection.selectAll(node, (node2) => node2 instanceof Class);
  }
  static selectByTag(node, tag) {
    return _Selection.selectAll(node, (node2) => node2.tag === tag);
  }
  createNode(datum, initializer, idx) {
    const node = this.nodeFactory(datum);
    node.datum = datum;
    initializer == null ? void 0 : initializer(node);
    if (idx != null) {
      this._nodes.splice(idx, 0, node);
    } else {
      this._nodes.push(node);
    }
    this.parentNode.appendChild(node);
    return node;
  }
  /**
   * Update the data in a selection. If an `getDatumId()` function is provided, maintain a list of ids related to
   * the nodes. Otherwise, take the more efficient route of simply creating and destroying nodes at the end
   * of the array.
   */
  update(data, initializer, getDatumId) {
    if (this.garbageBin.size > 0) {
      this.debug(`Selection - update() called with pending garbage: ${data}`);
    }
    if (getDatumId) {
      const dataMap = new Map(
        data.map((datum, idx) => [getDatumId(datum), [datum, idx]])
      );
      for (const [node, datumId] of this._nodesMap.entries()) {
        if (dataMap.has(datumId)) {
          const [newDatum] = dataMap.get(datumId);
          node.datum = newDatum;
          this.garbageBin.delete(node);
          dataMap.delete(datumId);
        } else {
          this.garbageBin.add(node);
        }
      }
      for (const [datumId, [datum, idx]] of dataMap.entries()) {
        this._nodesMap.set(this.createNode(datum, initializer, idx), datumId);
      }
    } else {
      const maxLength = Math.max(data.length, this.data.length);
      for (let i = 0; i < maxLength; i++) {
        if (i >= data.length) {
          this.garbageBin.add(this._nodes[i]);
        } else if (i >= this._nodes.length) {
          this.createNode(data[i], initializer);
        } else {
          this._nodes[i].datum = data[i];
          this.garbageBin.delete(this._nodes[i]);
        }
      }
    }
    this.data = data.slice();
    if (this.autoCleanup) {
      this.cleanup();
    }
    return this;
  }
  cleanup() {
    if (this.garbageBin.size === 0) {
      return this;
    }
    this._nodes = this._nodes.filter((node) => {
      if (this.garbageBin.has(node)) {
        this._nodesMap.delete(node);
        this.garbageBin.delete(node);
        this.parentNode.removeChild(node);
        return false;
      }
      return true;
    });
    return this;
  }
  clear() {
    this.update([]);
    return this;
  }
  isGarbage(node) {
    return this.garbageBin.has(node);
  }
  hasGarbage() {
    return this.garbageBin.size > 0;
  }
  each(iterate) {
    this._nodes.forEach((node, i) => iterate(node, node.datum, i));
    return this;
  }
  *[Symbol.iterator]() {
    for (let index = 0; index < this._nodes.length; index++) {
      const node = this._nodes[index];
      const datum = this._nodes[index].datum;
      yield { node, datum, index };
    }
  }
  select(predicate) {
    return _Selection.selectAll(this.parentNode, predicate);
  }
  selectByClass(Class) {
    return _Selection.selectByClass(this.parentNode, Class);
  }
  selectByTag(tag) {
    return _Selection.selectByTag(this.parentNode, tag);
  }
  nodes() {
    return this._nodes;
  }
};
function linearRoot(a, b) {
  const t = -b / a;
  return a !== 0 && t >= 0 && t <= 1 ? [t] : [];
}
function quadraticRoots(a, b, c) {
  if (a === 0) {
    return linearRoot(b, c);
  }
  const D = b * b - 4 * a * c;
  const roots = [];
  if (D === 0) {
    const t = -b / (2 * a);
    if (t >= 0 && t <= 1) {
      roots.push(t);
    }
  } else if (D > 0) {
    const rD = Math.sqrt(D);
    const t1 = (-b - rD) / (2 * a);
    const t2 = (-b + rD) / (2 * a);
    if (t1 >= 0 && t1 <= 1) {
      roots.push(t1);
    }
    if (t2 >= 0 && t2 <= 1) {
      roots.push(t2);
    }
  }
  return roots;
}
function cubicRoots(a, b, c, d) {
  if (a === 0) {
    return quadraticRoots(b, c, d);
  }
  const A = b / a;
  const B = c / a;
  const C = d / a;
  const Q = (3 * B - A * A) / 9;
  const R = (9 * A * B - 27 * C - 2 * A * A * A) / 54;
  const D = Q * Q * Q + R * R;
  const third = 1 / 3;
  const roots = [];
  if (D >= 0) {
    const rD = Math.sqrt(D);
    const S = Math.sign(R + rD) * Math.pow(Math.abs(R + rD), third);
    const T = Math.sign(R - rD) * Math.pow(Math.abs(R - rD), third);
    const Im = Math.abs(Math.sqrt(3) * (S - T) / 2);
    const t = -third * A + (S + T);
    if (t >= 0 && t <= 1) {
      roots.push(t);
    }
    if (Im === 0) {
      const t2 = -third * A - (S + T) / 2;
      if (t2 >= 0 && t2 <= 1) {
        roots.push(t2);
      }
    }
  } else {
    const theta = Math.acos(R / Math.sqrt(-Q * Q * Q));
    const thirdA = third * A;
    const twoSqrtQ = 2 * Math.sqrt(-Q);
    const t1 = twoSqrtQ * Math.cos(third * theta) - thirdA;
    const t2 = twoSqrtQ * Math.cos(third * (theta + 2 * Math.PI)) - thirdA;
    const t3 = twoSqrtQ * Math.cos(third * (theta + 4 * Math.PI)) - thirdA;
    if (t1 >= 0 && t1 <= 1) {
      roots.push(t1);
    }
    if (t2 >= 0 && t2 <= 1) {
      roots.push(t2);
    }
    if (t3 >= 0 && t3 <= 1) {
      roots.push(t3);
    }
  }
  return roots;
}
function segmentIntersection(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) {
  const d = (ax2 - ax1) * (by2 - by1) - (ay2 - ay1) * (bx2 - bx1);
  if (d === 0) {
    return null;
  }
  const ua = ((bx2 - bx1) * (ay1 - by1) - (ax1 - bx1) * (by2 - by1)) / d;
  const ub = ((ax2 - ax1) * (ay1 - by1) - (ay2 - ay1) * (ax1 - bx1)) / d;
  if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) {
    return {
      x: ax1 + ua * (ax2 - ax1),
      y: ay1 + ua * (ay2 - ay1)
    };
  }
  return null;
}
function cubicSegmentIntersections(px1, py1, px2, py2, px3, py3, px4, py4, x1, y1, x2, y2) {
  const intersections = [];
  const A = y1 - y2;
  const B = x2 - x1;
  const C = x1 * (y2 - y1) - y1 * (x2 - x1);
  const bx = bezierCoefficients(px1, px2, px3, px4);
  const by = bezierCoefficients(py1, py2, py3, py4);
  const a = A * bx[0] + B * by[0];
  const b = A * bx[1] + B * by[1];
  const c = A * bx[2] + B * by[2];
  const d = A * bx[3] + B * by[3] + C;
  const roots = cubicRoots(a, b, c, d);
  for (const t of roots) {
    const tt = t * t;
    const ttt = t * tt;
    const x = bx[0] * ttt + bx[1] * tt + bx[2] * t + bx[3];
    const y = by[0] * ttt + by[1] * tt + by[2] * t + by[3];
    let s;
    if (x1 !== x2) {
      s = (x - x1) / (x2 - x1);
    } else {
      s = (y - y1) / (y2 - y1);
    }
    if (s >= 0 && s <= 1) {
      intersections.push({ x, y });
    }
  }
  return intersections;
}
function bezierCoefficients(P1, P2, P3, P4) {
  return [
    // Bézier expressed as matrix operations:
    -P1 + 3 * P2 - 3 * P3 + P4,
    //                 |-1  3 -3  1| |P1|
    3 * P1 - 6 * P2 + 3 * P3,
    //   [t^3 t^2 t 1] | 3 -6  3  0| |P2|
    -3 * P1 + 3 * P2,
    //                 |-3  3  0  0| |P3|
    P1
    //                 | 1  0  0  0| |P4|
  ];
}
function arcIntersections(cx, cy, r, startAngle, endAngle, counterClockwise, x1, y1, x2, y2) {
  const k = (y2 - y1) / (x2 - x1);
  const y0 = y1 - k * x1;
  const a = Math.pow(k, 2) + 1;
  const b = 2 * (k * (y0 - cy) - cx);
  const c = Math.pow(cx, 2) + Math.pow(y0 - cy, 2) - Math.pow(r, 2);
  const d = Math.pow(b, 2) - 4 * a * c;
  if (d < 0) {
    return [];
  }
  const i1x = (-b + Math.sqrt(d)) / 2 / a;
  const i2x = (-b - Math.sqrt(d)) / 2 / a;
  const intersections = [];
  [i1x, i2x].forEach((x) => {
    const isXInsideLine = x >= Math.min(x1, x2) && x <= Math.max(x1, x2);
    if (!isXInsideLine) {
      return;
    }
    const y = k * x + y0;
    const a1 = normalizeAngle360(startAngle);
    let a2 = normalizeAngle360(endAngle);
    let a3 = normalizeAngle360(Math.atan2(y, x));
    if (a2 <= a1) {
      a2 += 2 * Math.PI;
    }
    if (a3 < a1) {
      a3 += 2 * Math.PI;
    }
    if (counterClockwise !== (a3 >= a1 && a3 <= a2)) {
      intersections.push({ x, y });
    }
  });
  return intersections;
}
var Path2D = class {
  constructor() {
    this.previousCommands = [];
    this.previousParams = [];
    this.previousClosedPath = false;
    this.commands = [];
    this.params = [];
    this._closedPath = false;
  }
  isDirty() {
    if (this._closedPath !== this.previousClosedPath) {
      return true;
    }
    if (this.previousCommands.length !== this.commands.length) {
      return true;
    }
    if (this.previousParams.length !== this.params.length) {
      return true;
    }
    for (let i = 0; i < this.commands.length; i++) {
      if (this.commands[i] !== this.previousCommands[i]) {
        return true;
      }
    }
    for (let i = 0; i < this.params.length; i++) {
      if (this.params[i] !== this.previousParams[i]) {
        return true;
      }
    }
    return false;
  }
  draw(ctx) {
    const commands = this.commands;
    const params = this.params;
    let j = 0;
    ctx.beginPath();
    for (const command of commands) {
      switch (command) {
        case 0:
          ctx.moveTo(params[j++], params[j++]);
          break;
        case 1:
          ctx.lineTo(params[j++], params[j++]);
          break;
        case 3:
          ctx.bezierCurveTo(params[j++], params[j++], params[j++], params[j++], params[j++], params[j++]);
          break;
        case 2:
          ctx.arc(params[j++], params[j++], params[j++], params[j++], params[j++], params[j++] === 1);
          break;
        case 4:
          ctx.closePath();
          break;
      }
    }
    if (commands.length === 0) {
      ctx.closePath();
    }
  }
  moveTo(x, y) {
    if (this.xy) {
      this.xy[0] = x;
      this.xy[1] = y;
    } else {
      this.xy = [x, y];
    }
    this.commands.push(
      0
      /* Move */
    );
    this.params.push(x, y);
  }
  lineTo(x, y) {
    if (this.xy) {
      this.commands.push(
        1
        /* Line */
      );
      this.params.push(x, y);
      this.xy[0] = x;
      this.xy[1] = y;
    } else {
      this.moveTo(x, y);
    }
  }
  rect(x, y, width, height) {
    this.moveTo(x, y);
    this.lineTo(x + width, y);
    this.lineTo(x + width, y + height);
    this.lineTo(x, y + height);
    this.closePath();
  }
  roundRect(x, y, width, height, radii) {
    radii = Math.min(radii, width / 2, height / 2);
    this.moveTo(x, y + radii);
    this.arc(x + radii, y + radii, radii, Math.PI, 3 * Math.PI / 2);
    this.lineTo(x + radii, y);
    this.lineTo(x + width - radii, y);
    this.arc(x + width - radii, y + radii, radii, 3 * Math.PI / 2, 2 * Math.PI);
    this.lineTo(x + width, y + radii);
    this.lineTo(x + width, y + height - radii);
    this.arc(x + width - radii, y + height - radii, radii, 0, Math.PI / 2);
    this.lineTo(x + width - radii, y + height);
    this.lineTo(x + radii, y + height);
    this.arc(x + +radii, y + height - radii, radii, Math.PI / 2, Math.PI);
    this.lineTo(x, y + height - radii);
    this.closePath();
  }
  arc(x, y, r, sAngle, eAngle, antiClockwise = false) {
    const endX = x + r * Math.cos(eAngle);
    const endY = y + r * Math.sin(eAngle);
    if (this.xy) {
      this.xy[0] = endX;
      this.xy[1] = endY;
    } else {
      this.xy = [endX, endY];
    }
    this.commands.push(
      2
      /* Arc */
    );
    this.params.push(x, y, r, sAngle, eAngle, antiClockwise ? 1 : 0);
  }
  cubicCurveTo(cx1, cy1, cx2, cy2, x, y) {
    if (!this.xy) {
      this.moveTo(cx1, cy1);
    }
    this.commands.push(
      3
      /* Curve */
    );
    this.params.push(cx1, cy1, cx2, cy2, x, y);
    if (this.xy) {
      this.xy[0] = x;
      this.xy[1] = y;
    }
  }
  get closedPath() {
    return this._closedPath;
  }
  closePath() {
    if (this.xy) {
      this.xy = void 0;
      this.commands.push(
        4
        /* ClosePath */
      );
      this._closedPath = true;
    }
  }
  clear({ trackChanges } = { trackChanges: false }) {
    if (trackChanges) {
      this.previousCommands = this.commands;
      this.previousParams = this.params;
      this.previousClosedPath = this._closedPath;
      this.commands = [];
      this.params = [];
    } else {
      this.commands.length = 0;
      this.params.length = 0;
    }
    this.xy = void 0;
    this._closedPath = false;
  }
  isPointInPath(x, y) {
    const commands = this.commands;
    const params = this.params;
    const cn = commands.length;
    const ox = -1e4;
    const oy = -1e4;
    let sx = NaN;
    let sy = NaN;
    let px = 0;
    let py = 0;
    let intersectionCount = 0;
    for (let ci = 0, pi = 0; ci < cn; ci++) {
      switch (commands[ci]) {
        case 0:
          if (!isNaN(sx) && segmentIntersection(sx, sy, px, py, ox, oy, x, y)) {
            intersectionCount++;
          }
          px = params[pi++];
          sx = px;
          py = params[pi++];
          sy = py;
          break;
        case 1:
          if (segmentIntersection(px, py, params[pi++], params[pi++], ox, oy, x, y)) {
            intersectionCount++;
          }
          px = params[pi - 2];
          py = params[pi - 1];
          break;
        case 3:
          intersectionCount += cubicSegmentIntersections(
            px,
            py,
            params[pi++],
            params[pi++],
            params[pi++],
            params[pi++],
            params[pi++],
            params[pi++],
            ox,
            oy,
            x,
            y
          ).length;
          px = params[pi - 2];
          py = params[pi - 1];
          break;
        case 2:
          const cx = params[pi++];
          const cy = params[pi++];
          const r = params[pi++];
          const startAngle = params[pi++];
          const endAngle = params[pi++];
          const counterClockwise = Boolean(params[pi++]);
          intersectionCount += arcIntersections(
            cx,
            cy,
            r,
            startAngle,
            endAngle,
            counterClockwise,
            ox,
            oy,
            x,
            y
          ).length;
          px = cx + Math.cos(endAngle) * r;
          py = cy + Math.sin(endAngle) * r;
          break;
        case 4:
          if (!isNaN(sx) && segmentIntersection(sx, sy, px, py, ox, oy, x, y)) {
            intersectionCount++;
          }
          break;
      }
    }
    return intersectionCount % 2 === 1;
  }
  getPoints() {
    const { commands, params } = this;
    const coords = [];
    let pi = 0;
    for (let ci = 0; ci < commands.length; ci++) {
      switch (commands[ci]) {
        case 0:
        case 1:
          coords.push({ x: params[pi++], y: params[pi++] });
          break;
        case 3:
          pi += 4;
          coords.push({ x: params[pi++], y: params[pi++] });
          break;
        case 2:
          coords.push({ x: params[pi++], y: params[pi++] });
          pi += 4;
          break;
        case 4:
          break;
      }
    }
    return coords;
  }
};
function ScenePathChangeDetection(opts) {
  const { redraw = 3, changeCb, convertor } = opts != null ? opts : {};
  return SceneChangeDetection({ redraw, type: "path", convertor, changeCb });
}
var Path = class extends Shape {
  constructor() {
    super(...arguments);
    this.path = new Path2D();
    this.clipScalingX = 1;
    this.clipScalingY = 1;
    this._dirtyPath = true;
  }
  set dirtyPath(value) {
    if (this._dirtyPath !== value) {
      this._dirtyPath = value;
      if (value) {
        this.markDirty(
          this,
          3
          /* MAJOR */
        );
      }
    }
  }
  get dirtyPath() {
    return this._dirtyPath;
  }
  checkPathDirty() {
    var _a, _b, _c, _d;
    if (this._dirtyPath) {
      return;
    }
    this.dirtyPath = this.path.isDirty() || ((_b = (_a = this.fillShadow) == null ? void 0 : _a.isDirty()) != null ? _b : false) || ((_d = (_c = this.clipPath) == null ? void 0 : _c.isDirty()) != null ? _d : false);
  }
  isPointInPath(x, y) {
    const point = this.transformPoint(x, y);
    return this.path.closedPath && this.path.isPointInPath(point.x, point.y);
  }
  isDirtyPath() {
    return false;
  }
  updatePath() {
  }
  clip(ctx, op) {
    const transform = ctx.getTransform();
    const clipScale = this.clipScalingX !== 1 || this.clipScalingY !== 1;
    if (clipScale) {
      ctx.scale(this.clipScalingX, this.clipScalingY);
    }
    op();
    if (clipScale) {
      ctx.setTransform(transform);
    }
  }
  render(renderCtx) {
    var _a;
    const { ctx, forceRender, stats } = renderCtx;
    if (this.dirty === 0 && !forceRender) {
      if (stats)
        stats.nodesSkipped += this.nodeCount.count;
      return;
    }
    this.computeTransformMatrix();
    this.matrix.toContext(ctx);
    if (this.dirtyPath || this.isDirtyPath()) {
      this.updatePath();
      this.dirtyPath = false;
    }
    if (this.clipPath && this.clipMode != null) {
      ctx.save();
      if (this.clipMode === "normal") {
        this.clip(ctx, () => {
          var _a2;
          (_a2 = this.clipPath) == null ? void 0 : _a2.draw(ctx);
          ctx.clip();
        });
      }
      if (this.clipScalingX > 0 && this.clipScalingY > 0) {
        this.path.draw(ctx);
        this.fillStroke(ctx);
      }
      if (this.clipMode === "punch-out") {
        this.clip(ctx, () => {
          var _a2, _b;
          (_a2 = this.clipPath) == null ? void 0 : _a2.draw(ctx);
          ctx.clip();
          const { x = -1e4, y = -1e4, width = 2e4, height = 2e4 } = (_b = this.computeBBox()) != null ? _b : {};
          ctx.clearRect(x, y, width, height);
        });
      }
      ctx.restore();
    } else {
      this.path.draw(ctx);
      this.fillStroke(ctx);
    }
    (_a = this.fillShadow) == null ? void 0 : _a.markClean();
    super.render(renderCtx);
  }
};
Path.className = "Path";
__decorateClass([
  ScenePathChangeDetection()
], Path.prototype, "clipPath", 2);
__decorateClass([
  ScenePathChangeDetection()
], Path.prototype, "clipMode", 2);
__decorateClass([
  ScenePathChangeDetection()
], Path.prototype, "clipScalingX", 2);
__decorateClass([
  ScenePathChangeDetection()
], Path.prototype, "clipScalingY", 2);
var Arc = class extends Path {
  constructor() {
    super();
    this.centerX = 0;
    this.centerY = 0;
    this.radius = 10;
    this.startAngle = 0;
    this.endAngle = Math.PI * 2;
    this.counterClockwise = false;
    this.type = 0;
    this.restoreOwnStyles();
  }
  get fullPie() {
    return isEqual(normalizeAngle360(this.startAngle), normalizeAngle360(this.endAngle));
  }
  updatePath() {
    const path = this.path;
    path.clear();
    path.arc(this.centerX, this.centerY, this.radius, this.startAngle, this.endAngle, this.counterClockwise);
    if (this.type === 1) {
      path.closePath();
    } else if (this.type === 2 && !this.fullPie) {
      path.lineTo(this.centerX, this.centerY);
      path.closePath();
    }
  }
  computeBBox() {
    return new BBox(this.centerX - this.radius, this.centerY - this.radius, this.radius * 2, this.radius * 2);
  }
  isPointInPath(x, y) {
    const point = this.transformPoint(x, y);
    const bbox = this.computeBBox();
    return this.type !== 0 && bbox.containsPoint(point.x, point.y) && this.path.isPointInPath(point.x, point.y);
  }
};
Arc.className = "Arc";
Arc.defaultStyles = Object.assign({}, Shape.defaultStyles, {
  lineWidth: 1,
  fillStyle: null
});
__decorateClass([
  ScenePathChangeDetection()
], Arc.prototype, "centerX", 2);
__decorateClass([
  ScenePathChangeDetection()
], Arc.prototype, "centerY", 2);
__decorateClass([
  ScenePathChangeDetection()
], Arc.prototype, "radius", 2);
__decorateClass([
  ScenePathChangeDetection()
], Arc.prototype, "startAngle", 2);
__decorateClass([
  ScenePathChangeDetection()
], Arc.prototype, "endAngle", 2);
__decorateClass([
  ScenePathChangeDetection()
], Arc.prototype, "counterClockwise", 2);
__decorateClass([
  ScenePathChangeDetection()
], Arc.prototype, "type", 2);
var Line = class extends Shape {
  constructor(opts = {}) {
    super(opts);
    this.x1 = 0;
    this.y1 = 0;
    this.x2 = 0;
    this.y2 = 0;
    this.restoreOwnStyles();
  }
  set x(value) {
    this.x1 = value;
    this.x2 = value;
  }
  set y(value) {
    this.y1 = value;
    this.y2 = value;
  }
  computeBBox() {
    return new BBox(
      Math.min(this.x1, this.x2),
      Math.min(this.y1, this.y2),
      Math.abs(this.x2 - this.x1),
      Math.abs(this.y2 - this.y1)
    );
  }
  isPointInPath(px, py) {
    if (this.x1 === this.x2 || this.y1 === this.y2) {
      const { x, y } = this.transformPoint(px, py);
      return this.computeBBox().grow(this.strokeWidth / 2).containsPoint(x, y);
    }
    return false;
  }
  render(renderCtx) {
    var _a;
    const { ctx, forceRender, stats, devicePixelRatio } = renderCtx;
    if (this.dirty === 0 && !forceRender) {
      if (stats)
        stats.nodesSkipped += this.nodeCount.count;
      return;
    }
    this.computeTransformMatrix();
    this.matrix.toContext(ctx);
    let { x1, y1, x2, y2 } = this;
    if (x1 === x2) {
      const { strokeWidth } = this;
      const x = Math.round(x1 * devicePixelRatio) / devicePixelRatio + Math.trunc(strokeWidth * devicePixelRatio) % 2 / (devicePixelRatio * 2);
      x1 = x;
      x2 = x;
    } else if (y1 === y2) {
      const { strokeWidth } = this;
      const y = Math.round(y1 * devicePixelRatio) / devicePixelRatio + Math.trunc(strokeWidth * devicePixelRatio) % 2 / (devicePixelRatio * 2);
      y1 = y;
      y2 = y;
    }
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    this.fillStroke(ctx);
    (_a = this.fillShadow) == null ? void 0 : _a.markClean();
    super.render(renderCtx);
  }
};
Line.className = "Line";
Line.defaultStyles = Object.assign({}, Shape.defaultStyles, {
  fill: void 0,
  strokeWidth: 1
});
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Line.prototype, "x1", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Line.prototype, "y1", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Line.prototype, "x2", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Line.prototype, "y2", 2);
var convertColorStringToOklcha = (v) => {
  const color = Color.fromString(v);
  const [l, c, h] = Color.RGBtoOKLCH(color.r, color.g, color.b);
  return { l, c, h, a: color.a };
};
var interpolateOklch = (x, y, d) => {
  d = Math.min(Math.max(d, 0), 1);
  let h;
  let c;
  if (Number.isNaN(x.h) && Number.isNaN(y.h)) {
    h = 0;
    c = 0;
  } else if (Number.isNaN(x.h)) {
    h = y.h;
    c = y.c;
  } else if (Number.isNaN(y.h)) {
    h = x.h;
    c = x.c;
  } else {
    const xH = x.h;
    let yH = y.h;
    const deltaH = y.h - x.h;
    if (deltaH > 180) {
      yH -= 360;
    } else if (deltaH < -180) {
      yH += 360;
    }
    h = xH * (1 - d) + yH * d;
    c = x.c * (1 - d) + y.c * d;
  }
  const l = x.l * (1 - d) + y.l * d;
  const a = x.a * (1 - d) + y.a * d;
  return Color.fromOKLCH(l, c, h, a);
};
var ColorScale = class {
  constructor() {
    this.invalid = true;
    this.domain = [0, 1];
    this.range = ["red", "blue"];
    this.parsedRange = this.range.map(convertColorStringToOklcha);
  }
  update() {
    const { domain, range: range3 } = this;
    if (domain.length < 2) {
      Logger.warnOnce("`colorDomain` should have at least 2 values.");
      if (domain.length === 0) {
        domain.push(0, 1);
      } else if (domain.length === 1) {
        domain.push(domain[0] + 1);
      }
    }
    for (let i = 1; i < domain.length; i++) {
      const a = domain[i - 1];
      const b = domain[i];
      if (a >= b) {
        Logger.warnOnce("`colorDomain` values should be supplied in ascending order.");
        domain.sort((a2, b2) => a2 - b2);
        break;
      }
    }
    if (range3.length < domain.length) {
      for (let i = range3.length; i < domain.length; i++) {
        range3.push(range3.length > 0 ? range3[0] : "black");
      }
    }
    this.parsedRange = this.range.map(convertColorStringToOklcha);
  }
  convert(x) {
    this.refresh();
    const { domain, range: range3, parsedRange } = this;
    const d0 = domain[0];
    const d1 = domain[domain.length - 1];
    const r0 = range3[0];
    const r1 = range3[range3.length - 1];
    if (x <= d0) {
      return r0;
    }
    if (x >= d1) {
      return r1;
    }
    let index;
    let q;
    if (domain.length === 2) {
      const t = (x - d0) / (d1 - d0);
      const step = 1 / (range3.length - 1);
      index = range3.length <= 2 ? 0 : Math.min(Math.floor(t * (range3.length - 1)), range3.length - 2);
      q = (t - index * step) / step;
    } else {
      for (index = 0; index < domain.length - 2; index++) {
        if (x < domain[index + 1]) {
          break;
        }
      }
      const a = domain[index];
      const b = domain[index + 1];
      q = (x - a) / (b - a);
    }
    const c0 = parsedRange[index];
    const c1 = parsedRange[index + 1];
    return interpolateOklch(c0, c1, q).toRgbaString();
  }
  refresh() {
    if (!this.invalid)
      return;
    this.invalid = false;
    this.update();
    if (this.invalid) {
      Logger.warnOnce("Expected update to not invalidate scale");
    }
  }
};
__decorateClass([
  Invalidating
], ColorScale.prototype, "domain", 2);
__decorateClass([
  Invalidating
], ColorScale.prototype, "range", 2);
var LinearGradientFill = class extends Shape {
  constructor() {
    super(...arguments);
    this.direction = "to-right";
    this.stops = void 0;
    this._mask = void 0;
  }
  get mask() {
    return this._mask;
  }
  set mask(newMask) {
    if (this._mask != null) {
      this.removeChild(this._mask);
    }
    if (newMask != null) {
      this.appendChild(newMask);
    }
    this._mask = newMask;
  }
  isPointInPath(x, y) {
    var _a, _b;
    return (_b = (_a = this.mask) == null ? void 0 : _a.isPointInPath(x, y)) != null ? _b : false;
  }
  computeBBox() {
    var _a;
    return (_a = this.mask) == null ? void 0 : _a.computeBBox();
  }
  render(renderCtx) {
    const { mask, stops } = this;
    const { ctx, devicePixelRatio } = renderCtx;
    const pixelLength = 1 / devicePixelRatio;
    const maskBbox = mask == null ? void 0 : mask.computeTransformedBBox();
    if (mask == null || stops == null || maskBbox == null)
      return;
    if (mask.dirtyPath) {
      mask.updatePath();
      mask.dirtyPath = false;
    }
    ctx.save();
    ctx.beginPath();
    mask.path.draw(ctx);
    ctx.clip();
    ctx.resetTransform();
    const x0 = Math.floor(maskBbox.x);
    const x1 = Math.ceil(maskBbox.x + maskBbox.width);
    const y0 = Math.floor(maskBbox.y);
    const y1 = Math.ceil(maskBbox.y + maskBbox.height);
    const colorScale = new ColorScale();
    const [i0, i1] = this.direction === "to-right" ? [x0, x1] : [y0, y1];
    colorScale.domain = stops.map((_, index) => {
      return i0 + (i1 - i0) * index / (stops.length - 1);
    });
    colorScale.range = stops;
    colorScale.update();
    if (this.direction === "to-right") {
      const height = y1 - y0;
      for (let x = x0; x <= x1; x += pixelLength) {
        ctx.fillStyle = colorScale.convert(x);
        ctx.fillRect(x, y0, pixelLength, height);
      }
    } else {
      const width = x1 - x0;
      for (let y = y0; y <= y1; y += pixelLength) {
        ctx.fillStyle = colorScale.convert(y);
        ctx.fillRect(x0, y, width, pixelLength);
      }
    }
    ctx.restore();
  }
};
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], LinearGradientFill.prototype, "direction", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], LinearGradientFill.prototype, "stops", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], LinearGradientFill.prototype, "_mask", 2);
var epsilon = 1e-6;
var cornerEdges = (leadingEdge, trailingEdge, leadingInset, trailingInset, cornerRadius) => {
  let leadingClipped = false;
  let trailingClipped = false;
  let leading0 = trailingInset - Math.sqrt(Math.max(__pow(cornerRadius, 2) - __pow(leadingInset, 2), 0));
  let leading1 = 0;
  let trailing0 = 0;
  let trailing1 = leadingInset - Math.sqrt(Math.max(__pow(cornerRadius, 2) - __pow(trailingInset, 2), 0));
  if (leading0 > leadingEdge) {
    leadingClipped = true;
    leading0 = leadingEdge;
    leading1 = leadingInset - Math.sqrt(Math.max(__pow(cornerRadius, 2) - __pow(trailingInset - leadingEdge, 2)));
  } else if (leading0 < epsilon) {
    leading0 = 0;
  }
  if (trailing1 > trailingEdge) {
    trailingClipped = true;
    trailing0 = trailingInset - Math.sqrt(Math.max(__pow(cornerRadius, 2) - __pow(leadingInset - trailingEdge, 2)));
    trailing1 = trailingEdge;
  } else if (trailing1 < epsilon) {
    trailing1 = 0;
  }
  return { leading0, leading1, trailing0, trailing1, leadingClipped, trailingClipped };
};
var drawCorner = (path, { x0, y0, x1, y1, cx, cy }, cornerRadius, move) => {
  if (move) {
    path.moveTo(x0, y0);
  }
  if (x0 !== x1 || y0 !== y1) {
    const r0 = Math.atan2(y0 - cy, x0 - cx);
    const r1 = Math.atan2(y1 - cy, x1 - cx);
    path.arc(cx, cy, cornerRadius, r0, r1);
  } else {
    path.lineTo(x0, y0);
  }
};
var insetCornerRadiusRect = (path, x, y, width, height, cornerRadii, cornerRadiusBbox) => {
  let {
    topLeft: topLeftCornerRadius,
    topRight: topRightCornerRadius,
    bottomRight: bottomRightCornerRadius,
    bottomLeft: bottomLeftCornerRadius
  } = cornerRadii;
  const maxVerticalCornerRadius = Math.max(
    topLeftCornerRadius + bottomLeftCornerRadius,
    topRightCornerRadius + bottomRightCornerRadius
  );
  const maxHorizontalCornerRadius = Math.max(
    topLeftCornerRadius + topRightCornerRadius,
    bottomLeftCornerRadius + bottomRightCornerRadius
  );
  if (maxVerticalCornerRadius <= 0 && maxHorizontalCornerRadius <= 0) {
    path.rect(x, y, width, height);
    return;
  } else if (cornerRadiusBbox == null && topLeftCornerRadius === topRightCornerRadius && topLeftCornerRadius === bottomRightCornerRadius && topLeftCornerRadius === bottomLeftCornerRadius) {
    path.roundRect(x, y, width, height, topLeftCornerRadius);
    return;
  }
  if (width < 0) {
    x += width;
    width = Math.abs(width);
  }
  if (height < 0) {
    y += height;
    height = Math.abs(height);
  }
  if (cornerRadiusBbox != null) {
    const x0 = Math.max(x, cornerRadiusBbox.x);
    const x1 = Math.min(x + width, cornerRadiusBbox.x + cornerRadiusBbox.width);
    const y0 = Math.max(y, cornerRadiusBbox.y);
    const y1 = Math.min(y + height, cornerRadiusBbox.y + cornerRadiusBbox.height);
    x = x0;
    y = y0;
    width = x1 - x0;
    height = y1 - y0;
  }
  if (width <= 0 || height <= 0)
    return;
  cornerRadiusBbox != null ? cornerRadiusBbox : cornerRadiusBbox = new BBox(x, y, width, height);
  const borderScale = Math.max(
    maxVerticalCornerRadius / cornerRadiusBbox.height,
    maxHorizontalCornerRadius / cornerRadiusBbox.width,
    1
  );
  if (borderScale > 1) {
    topLeftCornerRadius /= borderScale;
    topRightCornerRadius /= borderScale;
    bottomRightCornerRadius /= borderScale;
    bottomLeftCornerRadius /= borderScale;
  }
  let drawTopLeftCorner = true;
  let drawTopRightCorner = true;
  let drawBottomRightCorner = true;
  let drawBottomLeftCorner = true;
  let topLeftCorner;
  let topRightCorner;
  let bottomRightCorner;
  let bottomLeftCorner;
  if (drawTopLeftCorner) {
    const nodes = cornerEdges(
      height,
      width,
      Math.max(cornerRadiusBbox.x + topLeftCornerRadius - x, 0),
      Math.max(cornerRadiusBbox.y + topLeftCornerRadius - y, 0),
      topLeftCornerRadius
    );
    if (nodes.leadingClipped)
      drawBottomLeftCorner = false;
    if (nodes.trailingClipped)
      drawTopRightCorner = false;
    const x0 = Math.max(x + nodes.leading1, x);
    const y0 = Math.max(y + nodes.leading0, y);
    const x1 = Math.max(x + nodes.trailing1, x);
    const y1 = Math.max(y + nodes.trailing0, y);
    const cx = cornerRadiusBbox.x + topLeftCornerRadius;
    const cy = cornerRadiusBbox.y + topLeftCornerRadius;
    topLeftCorner = { x0, y0, x1, y1, cx, cy };
  }
  if (drawTopRightCorner) {
    const nodes = cornerEdges(
      width,
      height,
      Math.max(cornerRadiusBbox.y + topRightCornerRadius - y, 0),
      Math.max(x + width - (cornerRadiusBbox.x + cornerRadiusBbox.width - topRightCornerRadius), 0),
      topRightCornerRadius
    );
    if (nodes.leadingClipped)
      drawTopLeftCorner = false;
    if (nodes.trailingClipped)
      drawBottomRightCorner = false;
    const x0 = Math.min(x + width - nodes.leading0, x + width);
    const y0 = Math.max(y + nodes.leading1, y);
    const x1 = Math.min(x + width - nodes.trailing0, x + width);
    const y1 = Math.max(y + nodes.trailing1, y);
    const cx = cornerRadiusBbox.x + cornerRadiusBbox.width - topRightCornerRadius;
    const cy = cornerRadiusBbox.y + topRightCornerRadius;
    topRightCorner = { x0, y0, x1, y1, cx, cy };
  }
  if (drawBottomRightCorner) {
    const nodes = cornerEdges(
      height,
      width,
      Math.max(x + width - (cornerRadiusBbox.x + cornerRadiusBbox.width - bottomRightCornerRadius), 0),
      Math.max(y + height - (cornerRadiusBbox.y + cornerRadiusBbox.height - bottomRightCornerRadius), 0),
      bottomRightCornerRadius
    );
    if (nodes.leadingClipped)
      drawTopRightCorner = false;
    if (nodes.trailingClipped)
      drawBottomLeftCorner = false;
    const x0 = Math.min(x + width - nodes.leading1, x + width);
    const y0 = Math.min(y + height - nodes.leading0, y + height);
    const x1 = Math.min(x + width - nodes.trailing1, x + width);
    const y1 = Math.min(y + height - nodes.trailing0, y + height);
    const cx = cornerRadiusBbox.x + cornerRadiusBbox.width - bottomRightCornerRadius;
    const cy = cornerRadiusBbox.y + cornerRadiusBbox.height - bottomRightCornerRadius;
    bottomRightCorner = { x0, y0, x1, y1, cx, cy };
  }
  if (drawBottomLeftCorner) {
    const nodes = cornerEdges(
      width,
      height,
      Math.max(y + height - (cornerRadiusBbox.y + cornerRadiusBbox.height - bottomLeftCornerRadius), 0),
      Math.max(cornerRadiusBbox.x + bottomLeftCornerRadius - x, 0),
      bottomLeftCornerRadius
    );
    if (nodes.leadingClipped)
      drawBottomRightCorner = false;
    if (nodes.trailingClipped)
      drawTopLeftCorner = false;
    const x0 = Math.max(x + nodes.leading0, x);
    const y0 = Math.min(y + height - nodes.leading1, y + height);
    const x1 = Math.max(x + nodes.trailing0, x);
    const y1 = Math.min(y + height - nodes.trailing1, y + height);
    const cx = cornerRadiusBbox.x + bottomLeftCornerRadius;
    const cy = cornerRadiusBbox.y + cornerRadiusBbox.height - bottomLeftCornerRadius;
    bottomLeftCorner = { x0, y0, x1, y1, cx, cy };
  }
  let didMove = false;
  if (drawTopLeftCorner && topLeftCorner != null) {
    drawCorner(path, topLeftCorner, topLeftCornerRadius, !didMove);
    didMove || (didMove = true);
  }
  if (drawTopRightCorner && topRightCorner != null) {
    drawCorner(path, topRightCorner, topRightCornerRadius, !didMove);
    didMove || (didMove = true);
  }
  if (drawBottomRightCorner && bottomRightCorner != null) {
    drawCorner(path, bottomRightCorner, bottomRightCornerRadius, !didMove);
    didMove || (didMove = true);
  }
  if (drawBottomLeftCorner && bottomLeftCorner != null) {
    drawCorner(path, bottomLeftCorner, bottomLeftCornerRadius, !didMove);
    didMove || (didMove = true);
  }
  path.closePath();
};
var Rect = class extends Path {
  constructor() {
    super(...arguments);
    this.borderPath = new Path2D();
    this.x = 0;
    this.y = 0;
    this.width = 10;
    this.height = 10;
    this.topLeftCornerRadius = 0;
    this.topRightCornerRadius = 0;
    this.bottomRightCornerRadius = 0;
    this.bottomLeftCornerRadius = 0;
    this.cornerRadiusBbox = void 0;
    this.crisp = false;
    this.lastUpdatePathStrokeWidth = Shape.defaultStyles.strokeWidth;
    this.effectiveStrokeWidth = Shape.defaultStyles.strokeWidth;
    this.microPixelEffectOpacity = 1;
  }
  set cornerRadius(cornerRadius) {
    this.topLeftCornerRadius = cornerRadius;
    this.topRightCornerRadius = cornerRadius;
    this.bottomRightCornerRadius = cornerRadius;
    this.bottomLeftCornerRadius = cornerRadius;
  }
  isDirtyPath() {
    var _a;
    if (this.lastUpdatePathStrokeWidth !== this.strokeWidth) {
      return true;
    }
    return !!(this.path.isDirty() || this.borderPath.isDirty() || ((_a = this.clipPath) == null ? void 0 : _a.isDirty()));
  }
  updatePath() {
    var _a, _b, _c;
    const {
      path,
      borderPath,
      crisp,
      topLeftCornerRadius,
      topRightCornerRadius,
      bottomRightCornerRadius,
      bottomLeftCornerRadius
    } = this;
    let { x, y, width: w, height: h, strokeWidth, cornerRadiusBbox } = this;
    const pixelRatio = (_b = (_a = this.layerManager) == null ? void 0 : _a.canvas.pixelRatio) != null ? _b : 1;
    const pixelSize = 1 / pixelRatio;
    let microPixelEffectOpacity = 1;
    path.clear({ trackChanges: true });
    borderPath.clear({ trackChanges: true });
    if (crisp) {
      if (w <= pixelSize) {
        microPixelEffectOpacity *= w / pixelSize;
      }
      if (h <= pixelSize) {
        microPixelEffectOpacity *= h / pixelSize;
      }
      w = this.align(x, w);
      h = this.align(y, h);
      x = this.align(x);
      y = this.align(y);
      cornerRadiusBbox = cornerRadiusBbox != null ? new BBox(
        this.align(cornerRadiusBbox.x),
        this.align(cornerRadiusBbox.y),
        this.align(cornerRadiusBbox.x, cornerRadiusBbox.width),
        this.align(cornerRadiusBbox.y, cornerRadiusBbox.height)
      ) : void 0;
    }
    if (strokeWidth) {
      if (w < pixelSize) {
        const lx = x + pixelSize / 2;
        borderPath.moveTo(lx, y);
        borderPath.lineTo(lx, y + h);
        strokeWidth = pixelSize;
        this.borderClipPath = void 0;
      } else if (h < pixelSize) {
        const ly = y + pixelSize / 2;
        borderPath.moveTo(x, ly);
        borderPath.lineTo(x + w, ly);
        strokeWidth = pixelSize;
        this.borderClipPath = void 0;
      } else if (strokeWidth < w && strokeWidth < h) {
        const halfStrokeWidth = strokeWidth / 2;
        x += halfStrokeWidth;
        y += halfStrokeWidth;
        w -= strokeWidth;
        h -= strokeWidth;
        const adjustedCornerRadiusBbox = cornerRadiusBbox == null ? void 0 : cornerRadiusBbox.clone().shrink(halfStrokeWidth);
        const cornerRadii = {
          topLeft: topLeftCornerRadius > 0 ? topLeftCornerRadius - strokeWidth : 0,
          topRight: topRightCornerRadius > 0 ? topRightCornerRadius - strokeWidth : 0,
          bottomRight: bottomRightCornerRadius > 0 ? bottomRightCornerRadius - strokeWidth : 0,
          bottomLeft: bottomLeftCornerRadius > 0 ? bottomLeftCornerRadius - strokeWidth : 0
        };
        this.borderClipPath = void 0;
        insetCornerRadiusRect(path, x, y, w, h, cornerRadii, adjustedCornerRadiusBbox);
        insetCornerRadiusRect(borderPath, x, y, w, h, cornerRadii, adjustedCornerRadiusBbox);
      } else {
        this.borderClipPath = (_c = this.borderClipPath) != null ? _c : new Path2D();
        this.borderClipPath.clear({ trackChanges: true });
        this.borderClipPath.rect(x, y, w, h);
        borderPath.rect(x, y, w, h);
      }
    } else {
      const cornerRadii = {
        topLeft: topLeftCornerRadius,
        topRight: topRightCornerRadius,
        bottomRight: bottomRightCornerRadius,
        bottomLeft: bottomLeftCornerRadius
      };
      this.borderClipPath = void 0;
      insetCornerRadiusRect(path, x, y, w, h, cornerRadii, cornerRadiusBbox);
    }
    this.effectiveStrokeWidth = strokeWidth;
    this.lastUpdatePathStrokeWidth = strokeWidth;
    this.microPixelEffectOpacity = microPixelEffectOpacity;
  }
  computeBBox() {
    const { x, y, width, height } = this;
    return new BBox(x, y, width, height);
  }
  isPointInPath(x, y) {
    const point = this.transformPoint(x, y);
    const bbox = this.computeBBox();
    return bbox.containsPoint(point.x, point.y);
  }
  applyFillAlpha(ctx) {
    const { fillOpacity, microPixelEffectOpacity, opacity } = this;
    const { globalAlpha } = ctx;
    ctx.globalAlpha = globalAlpha * opacity * fillOpacity * microPixelEffectOpacity;
  }
  renderStroke(ctx) {
    const { stroke, effectiveStrokeWidth, borderPath, borderClipPath, opacity, microPixelEffectOpacity } = this;
    const borderActive = !!stroke && !!effectiveStrokeWidth;
    if (borderActive) {
      const { strokeOpacity, lineDash, lineDashOffset, lineCap, lineJoin } = this;
      if (borderClipPath) {
        borderClipPath.draw(ctx);
        ctx.clip();
      }
      borderPath.draw(ctx);
      const { globalAlpha } = ctx;
      ctx.strokeStyle = stroke;
      ctx.globalAlpha = globalAlpha * opacity * strokeOpacity * microPixelEffectOpacity;
      ctx.lineWidth = effectiveStrokeWidth;
      if (lineDash) {
        ctx.setLineDash(lineDash);
      }
      if (lineDashOffset) {
        ctx.lineDashOffset = lineDashOffset;
      }
      if (lineCap) {
        ctx.lineCap = lineCap;
      }
      if (lineJoin) {
        ctx.lineJoin = lineJoin;
      }
      ctx.stroke();
      ctx.globalAlpha = globalAlpha;
    }
  }
};
Rect.className = "Rect";
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "x", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "y", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "width", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "height", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "topLeftCornerRadius", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "topRightCornerRadius", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "bottomRightCornerRadius", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "bottomLeftCornerRadius", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "cornerRadiusBbox", 2);
__decorateClass([
  ScenePathChangeDetection()
], Rect.prototype, "crisp", 2);
function isPointInSector(x, y, sector) {
  const radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
  const { innerRadius, outerRadius } = sector;
  if (sector.startAngle === sector.endAngle || radius < Math.min(innerRadius, outerRadius) || radius > Math.max(innerRadius, outerRadius)) {
    return false;
  }
  const startAngle = normalizeAngle180(sector.startAngle);
  const endAngle = normalizeAngle180(sector.endAngle);
  const angle = Math.atan2(y, x);
  return startAngle < endAngle ? angle <= endAngle && angle >= startAngle : angle <= endAngle && angle >= -Math.PI || angle >= startAngle && angle <= Math.PI;
}
function lineCollidesSector(line, sector) {
  const { startAngle, endAngle, innerRadius, outerRadius } = sector;
  const outerStart = { x: outerRadius * Math.cos(startAngle), y: outerRadius * Math.sin(startAngle) };
  const outerEnd = { x: outerRadius * Math.cos(endAngle), y: outerRadius * Math.sin(endAngle) };
  const innerStart = innerRadius === 0 ? { x: 0, y: 0 } : { x: innerRadius * Math.cos(startAngle), y: innerRadius * Math.sin(startAngle) };
  const innerEnd = innerRadius === 0 ? { x: 0, y: 0 } : { x: innerRadius * Math.cos(endAngle), y: innerRadius * Math.sin(endAngle) };
  return segmentIntersection(
    line.start.x,
    line.start.y,
    line.end.x,
    line.end.y,
    outerStart.x,
    outerStart.y,
    innerStart.x,
    innerStart.y
  ) != null || segmentIntersection(
    line.start.x,
    line.start.y,
    line.end.x,
    line.end.y,
    outerEnd.x,
    outerEnd.y,
    innerEnd.x,
    innerEnd.y
  ) != null || arcIntersections(
    0,
    0,
    outerRadius,
    startAngle,
    endAngle,
    true,
    line.start.x,
    line.start.y,
    line.end.x,
    line.end.y
  ).length > 0;
}
function boxCollidesSector(box, sector) {
  const topLeft = { x: box.x, y: box.y };
  const topRight = { x: box.x + box.width, y: box.y };
  const bottomLeft = { x: box.x, y: box.y + box.height };
  const bottomRight = { x: box.x + box.width, y: box.y + box.height };
  return lineCollidesSector({ start: topLeft, end: topRight }, sector) || lineCollidesSector({ start: bottomLeft, end: bottomRight }, sector);
}
var Sector = class extends Path {
  constructor() {
    super(...arguments);
    this.centerX = 0;
    this.centerY = 0;
    this.innerRadius = 10;
    this.outerRadius = 20;
    this.startAngle = 0;
    this.endAngle = Math.PI * 2;
    this.angleOffset = 0;
    this.inset = 0;
  }
  computeBBox() {
    const radius = this.outerRadius;
    return new BBox(this.centerX - radius, this.centerY - radius, radius * 2, radius * 2);
  }
  updatePath() {
    const path = this.path;
    const { angleOffset, inset } = this;
    const startAngle = this.startAngle + angleOffset;
    const endAngle = this.endAngle + angleOffset;
    const sweep = startAngle <= endAngle ? endAngle - startAngle : Math.PI * 2 - (startAngle - endAngle);
    const innerRadius = Math.max(Math.min(this.innerRadius, this.outerRadius) + inset, 0);
    const outerRadius = Math.max(Math.max(this.innerRadius, this.outerRadius) - inset, 0);
    const fullPie = sweep >= 2 * Math.PI;
    const centerX = this.centerX;
    const centerY = this.centerY;
    path.clear();
    if (fullPie) {
      path.arc(centerX, centerY, outerRadius, startAngle, endAngle);
      if (innerRadius > inset) {
        path.moveTo(centerX + innerRadius * Math.cos(endAngle), centerY + innerRadius * Math.sin(endAngle));
        path.arc(centerX, centerY, innerRadius, endAngle, startAngle, true);
      }
    } else {
      const innerAngleOffset = innerRadius > 0 ? inset / innerRadius : 0;
      const outerAngleOffset = outerRadius > 0 ? inset / outerRadius : 0;
      const outerAngleExceeded = sweep < 2 * outerAngleOffset;
      if (outerAngleExceeded)
        return;
      const innerAngleExceeded = innerRadius <= inset || sweep < 2 * innerAngleOffset;
      if (innerAngleExceeded) {
        const x = sweep < Math.PI * 0.5 ? inset * (1 + Math.cos(sweep)) / Math.sin(sweep) : NaN;
        let r;
        if (x > 0 && x < outerRadius) {
          r = Math.max(Math.hypot(inset, x), innerRadius);
        } else {
          r = innerRadius;
        }
        const midAngle = startAngle + sweep * 0.5;
        path.moveTo(centerX + r * Math.cos(midAngle), centerY + r * Math.sin(midAngle));
      } else {
        path.moveTo(
          centerX + innerRadius * Math.cos(startAngle + innerAngleOffset),
          centerY + innerRadius * Math.sin(startAngle + innerAngleOffset)
        );
      }
      path.arc(centerX, centerY, outerRadius, startAngle + outerAngleOffset, endAngle - outerAngleOffset);
      if (innerAngleExceeded) {
      } else if (innerRadius > 0) {
        path.arc(
          centerX,
          centerY,
          innerRadius,
          endAngle - innerAngleOffset,
          startAngle + innerAngleOffset,
          true
        );
      } else {
        path.lineTo(centerX, centerY);
      }
    }
    path.closePath();
    this.dirtyPath = false;
  }
  isPointInPath(x, y) {
    const { angleOffset } = this;
    const startAngle = this.startAngle + angleOffset;
    const endAngle = this.endAngle + angleOffset;
    const innerRadius = Math.min(this.innerRadius, this.outerRadius);
    const outerRadius = Math.max(this.innerRadius, this.outerRadius);
    const point = this.transformPoint(x, y);
    return isPointInSector(point.x, point.y, { startAngle, endAngle, innerRadius, outerRadius });
  }
};
Sector.className = "Sector";
__decorateClass([
  ScenePathChangeDetection()
], Sector.prototype, "centerX", 2);
__decorateClass([
  ScenePathChangeDetection()
], Sector.prototype, "centerY", 2);
__decorateClass([
  ScenePathChangeDetection()
], Sector.prototype, "innerRadius", 2);
__decorateClass([
  ScenePathChangeDetection()
], Sector.prototype, "outerRadius", 2);
__decorateClass([
  ScenePathChangeDetection()
], Sector.prototype, "startAngle", 2);
__decorateClass([
  ScenePathChangeDetection()
], Sector.prototype, "endAngle", 2);
__decorateClass([
  ScenePathChangeDetection()
], Sector.prototype, "angleOffset", 2);
__decorateClass([
  ScenePathChangeDetection()
], Sector.prototype, "inset", 2);
var group = (content) => `(${content})`;
var optionalGroup = (content) => `${group(content)}?`;
var nonCapturingGroup = (content) => optionalGroup(`?:${content}`);
var formatRegEx = (() => {
  const fill = ".";
  const align = "[<>=^]";
  const sign = "[+\\-( ]";
  const symbol = "[$\u20AC\xA3\xA5\u20A3\u20B9#]";
  const zero = "0";
  const width = "\\d+";
  const comma = ",";
  const precision = "\\d+";
  const tilde = "~";
  const type = "[%a-z]";
  return new RegExp(
    [
      "^",
      nonCapturingGroup(`${optionalGroup(fill)}${group(align)}`),
      optionalGroup(sign),
      optionalGroup(symbol),
      optionalGroup(zero),
      optionalGroup(width),
      optionalGroup(comma),
      nonCapturingGroup(`\\.${group(precision)}`),
      optionalGroup(tilde),
      optionalGroup(type),
      "$"
    ].join(""),
    "i"
  );
})();
var surroundedRegEx = (() => {
  const prefix = ".*?";
  const content = ".+?";
  const suffix = ".*?";
  return new RegExp(["^", group(prefix), `#\\{${group(content)}\\}`, group(suffix), "$"].join(""));
})();
function parseFormatter(formatter) {
  let prefix;
  let suffix;
  const surrounded = surroundedRegEx.exec(formatter);
  if (surrounded) {
    [, prefix, formatter, suffix] = surrounded;
  }
  const match = formatRegEx.exec(formatter);
  if (!match) {
    throw new Error(`The number formatter is invalid: ${formatter}`);
  }
  const [, fill, align, sign, symbol, zero, width, comma, precision, trim, type] = match;
  return {
    fill,
    align,
    sign,
    symbol,
    zero,
    width: parseInt(width),
    comma,
    precision: parseInt(precision),
    trim: Boolean(trim),
    type,
    prefix,
    suffix
  };
}
function format(formatter) {
  const options = typeof formatter === "string" ? parseFormatter(formatter) : formatter;
  const { fill, align, sign = "-", symbol, zero, width, comma, type, prefix = "", suffix = "", precision } = options;
  let { trim } = options;
  const precisionIsNaN = precision === void 0 || isNaN(precision);
  let formatBody;
  if (!type) {
    formatBody = decimalTypes["g"];
    trim = true;
  } else if (type in decimalTypes && type in integerTypes) {
    formatBody = precisionIsNaN ? integerTypes[type] : decimalTypes[type];
  } else if (type in decimalTypes) {
    formatBody = decimalTypes[type];
  } else if (type in integerTypes) {
    formatBody = integerTypes[type];
  } else {
    throw new Error(`The number formatter type is invalid: ${type}`);
  }
  let formatterPrecision;
  if (precision == null || precisionIsNaN) {
    formatterPrecision = type ? 6 : 12;
  } else {
    formatterPrecision = precision;
  }
  return (n) => {
    let result = formatBody(n, formatterPrecision);
    if (trim) {
      result = removeTrailingZeros(result);
    }
    if (comma) {
      result = insertSeparator(result, comma);
    }
    result = addSign(n, result, sign);
    if (symbol && symbol !== "#") {
      result = `${symbol}${result}`;
    }
    if (symbol === "#" && type === "x") {
      result = `0x${result}`;
    }
    if (type === "s") {
      result = `${result}${getSIPrefix(n)}`;
    }
    if (type === "%" || type === "p") {
      result = `${result}%`;
    }
    if (width != null && !isNaN(width)) {
      result = addPadding(result, width, fill != null ? fill : zero, align);
    }
    result = `${prefix}${result}${suffix}`;
    return result;
  };
}
var absFloor = (n) => Math.floor(Math.abs(n));
var integerTypes = {
  b: (n) => absFloor(n).toString(2),
  c: (n) => String.fromCharCode(n),
  d: (n) => Math.round(Math.abs(n)).toFixed(0),
  o: (n) => absFloor(n).toString(8),
  x: (n) => absFloor(n).toString(16),
  X: (n) => integerTypes.x(n).toUpperCase(),
  n: (n) => integerTypes.d(n),
  "%": (n) => `${absFloor(n * 100).toFixed(0)}`
};
var decimalTypes = {
  e: (n, f) => Math.abs(n).toExponential(f),
  E: (n, f) => decimalTypes.e(n, f).toUpperCase(),
  f: (n, f) => Math.abs(n).toFixed(f),
  F: (n, f) => decimalTypes.f(n, f).toUpperCase(),
  g: (n, f) => {
    if (n === 0) {
      return "0";
    }
    const a = Math.abs(n);
    const p = Math.floor(Math.log10(a));
    if (p >= -4 && p < f) {
      return a.toFixed(f - 1 - p);
    }
    return a.toExponential(f - 1);
  },
  G: (n, f) => decimalTypes.g(n, f).toUpperCase(),
  n: (n, f) => decimalTypes.g(n, f),
  p: (n, f) => decimalTypes.r(n * 100, f),
  r: (n, f) => {
    if (n === 0) {
      return "0";
    }
    const a = Math.abs(n);
    const p = Math.floor(Math.log10(a));
    const q = p - (f - 1);
    if (q <= 0) {
      return a.toFixed(-q);
    }
    const x = Math.pow(10, q);
    return (Math.round(a / x) * x).toFixed();
  },
  s: (n, f) => {
    const p = getSIPrefixPower(n);
    return decimalTypes.r(n / Math.pow(10, p), f);
  },
  "%": (n, f) => decimalTypes.f(n * 100, f)
};
function removeTrailingZeros(numString) {
  return numString.replace(/\.0+$/, "").replace(/(\.[1-9])0+$/, "$1");
}
function insertSeparator(numString, separator) {
  let dotIndex = numString.indexOf(".");
  if (dotIndex < 0) {
    dotIndex = numString.length;
  }
  const integerChars = numString.substring(0, dotIndex).split("");
  const fractionalPart = numString.substring(dotIndex);
  for (let i = integerChars.length - 3; i > 0; i -= 3) {
    integerChars.splice(i, 0, separator);
  }
  return `${integerChars.join("")}${fractionalPart}`;
}
function getSIPrefix(n) {
  return siPrefixes[getSIPrefixPower(n)];
}
function getSIPrefixPower(n) {
  const power = Math.log10(Math.abs(n));
  const p = Math.floor(power / 3) * 3;
  return Math.max(minSIPrefix, Math.min(maxSIPrefix, p));
}
var minSIPrefix = -24;
var maxSIPrefix = 24;
var siPrefixes = {
  [minSIPrefix]: "y",
  [-21]: "z",
  [-18]: "a",
  [-15]: "f",
  [-12]: "p",
  [-9]: "n",
  [-6]: "\xB5",
  [-3]: "m",
  [0]: "",
  [3]: "k",
  [6]: "M",
  [9]: "G",
  [12]: "T",
  [15]: "P",
  [18]: "E",
  [21]: "Z",
  [maxSIPrefix]: "Y"
};
var minusSign = "\u2212";
function addSign(num, numString, signType = "") {
  if (signType === "(") {
    return num >= 0 ? numString : `(${numString})`;
  }
  const plusSign = signType === "+" ? "+" : "";
  return `${num >= 0 ? plusSign : minusSign}${numString}`;
}
function addPadding(numString, width, fill = " ", align = ">") {
  let result = numString;
  if (align === ">" || !align) {
    result = result.padStart(width, fill);
  } else if (align === "<") {
    result = result.padEnd(width, fill);
  } else if (align === "^") {
    const padWidth = Math.max(0, width - result.length);
    const padLeft = Math.ceil(padWidth / 2);
    const padRight = Math.floor(padWidth / 2);
    result = result.padStart(padLeft + result.length, fill);
    result = result.padEnd(padRight + result.length, fill);
  }
  return result;
}
function tickFormat(ticks, formatter) {
  const options = parseFormatter(formatter != null ? formatter : ",f");
  const { precision } = options;
  if (precision == null || isNaN(precision)) {
    if (options.type === "f" || options.type === "%") {
      options.precision = Math.max(
        ...ticks.map((x) => {
          if (typeof x !== "number" || x === 0) {
            return 0;
          }
          const l = Math.floor(Math.log10(Math.abs(x)));
          const digits = options.type ? 6 : 12;
          const exp = x.toExponential(digits - 1).replace(/\.?0+e/, "e");
          const dotIndex = exp.indexOf(".");
          if (dotIndex < 0) {
            return l >= 0 ? 0 : -l;
          }
          const s = exp.indexOf("e") - dotIndex;
          return Math.max(0, s - l - 1);
        })
      );
    } else if (!options.type || options.type in decimalTypes) {
      options.precision = Math.max(
        ...ticks.map((x) => {
          if (typeof x !== "number") {
            return 0;
          }
          const exp = x.toExponential((options.type ? 6 : 12) - 1).replace(/\.?0+e/, "e");
          return exp.substring(0, exp.indexOf("e")).replace(".", "").length;
        })
      );
    }
  }
  const f = format(options);
  return (n) => f(Number(n));
}
var createNumericTicks = (fractionDigits, takingValues = []) => Object.assign(takingValues, { fractionDigits });
function ticks_default(start, stop, count2, minCount, maxCount) {
  if (count2 < 2) {
    return range(start, stop, stop - start);
  }
  const step = tickStep(start, stop, count2, minCount, maxCount);
  if (isNaN(step)) {
    return createNumericTicks(0);
  }
  start = Math.ceil(start / step) * step;
  stop = Math.floor(stop / step) * step;
  return range(start, stop, step);
}
var tickMultipliers = [1, 2, 5, 10];
function tickStep(a, b, count2, minCount = 0, maxCount = Infinity) {
  const extent2 = Math.abs(b - a);
  const rawStep = extent2 / count2;
  const power = Math.floor(Math.log10(rawStep));
  const step = Math.pow(10, power);
  const m = tickMultipliers.map((multiplier) => {
    const s = multiplier * step;
    const c = Math.ceil(extent2 / s);
    const isWithinBounds = c >= minCount && c <= maxCount;
    const diffCount = Math.abs(c - count2);
    return { multiplier, isWithinBounds, diffCount };
  }).sort((a2, b2) => {
    if (a2.isWithinBounds !== b2.isWithinBounds) {
      return a2.isWithinBounds ? -1 : 1;
    }
    return a2.diffCount - b2.diffCount;
  })[0].multiplier;
  if (!m || isNaN(m)) {
    return NaN;
  }
  return m * step;
}
function singleTickDomain(a, b) {
  const extent2 = Math.abs(b - a);
  const power = Math.floor(Math.log10(extent2));
  const step = Math.pow(10, power);
  const roundStart = a > b ? Math.ceil : Math.floor;
  const roundStop = b < a ? Math.floor : Math.ceil;
  return tickMultipliers.map((multiplier) => {
    const s = multiplier * step;
    const start = roundStart(a / s) * s;
    const end = roundStop(b / s) * s;
    const error = 1 - extent2 / Math.abs(end - start);
    const domain = [start, end];
    return { error, domain };
  }).sort((a2, b2) => a2.error - b2.error)[0].domain;
}
function range(start, stop, step) {
  const d0 = Math.min(start, stop);
  const d1 = Math.max(start, stop);
  const fractionalDigits = countFractionDigits(step);
  const f = Math.pow(10, fractionalDigits);
  const n = Math.ceil((d1 - d0) / step);
  const values = createNumericTicks(fractionalDigits);
  for (let i = 0; i <= n; i++) {
    const value = d0 + step * i;
    values.push(Math.round(value * f) / f);
  }
  return values;
}
var LinearScale = class extends ContinuousScale {
  constructor() {
    super([0, 1], [0, 1]);
    this.type = "linear";
  }
  toDomain(d) {
    return d;
  }
  ticks() {
    var _a;
    const count2 = (_a = this.tickCount) != null ? _a : ContinuousScale.defaultTickCount;
    if (!this.domain || this.domain.length < 2 || count2 < 1 || this.domain.some((d) => !isFinite(d))) {
      return [];
    }
    this.refresh();
    const [d0, d1] = this.getDomain();
    const { interval } = this;
    if (interval) {
      const step = Math.abs(interval);
      if (!this.isDenseInterval({ start: d0, stop: d1, interval: step })) {
        return range(d0, d1, step);
      }
    }
    return ticks_default(d0, d1, count2, this.minTickCount, this.maxTickCount);
  }
  update() {
    if (!this.domain || this.domain.length < 2) {
      return;
    }
    if (this.nice) {
      this.updateNiceDomain();
    }
  }
  getTickStep(start, stop) {
    var _a, _b;
    const count2 = (_a = this.tickCount) != null ? _a : ContinuousScale.defaultTickCount;
    return (_b = this.interval) != null ? _b : tickStep(start, stop, count2, this.minTickCount, this.maxTickCount);
  }
  /**
   * Extends the domain so that it starts and ends on nice round values.
   */
  updateNiceDomain() {
    var _a;
    const count2 = (_a = this.tickCount) != null ? _a : ContinuousScale.defaultTickCount;
    if (count2 < 1) {
      this.niceDomain = [...this.domain];
      return;
    }
    let [start, stop] = this.domain;
    if (count2 === 1) {
      [start, stop] = singleTickDomain(start, stop);
    } else {
      const roundStart = start > stop ? Math.ceil : Math.floor;
      const roundStop = stop < start ? Math.floor : Math.ceil;
      const maxAttempts = 4;
      for (let i = 0; i < maxAttempts; i++) {
        const prev0 = start;
        const prev1 = stop;
        const step = this.getTickStep(start, stop);
        const [d0, d1] = this.domain;
        if (step >= 1) {
          start = roundStart(d0 / step) * step;
          stop = roundStop(d1 / step) * step;
        } else {
          const s = 1 / step;
          start = roundStart(d0 * s) / s;
          stop = roundStop(d1 * s) / s;
        }
        if (start === prev0 && stop === prev1) {
          break;
        }
      }
    }
    this.niceDomain = [start, stop];
  }
  tickFormat({ ticks, specifier }) {
    return tickFormat(ticks != null ? ticks : this.ticks(), specifier);
  }
};
var Marker = class extends Path {
  constructor() {
    super(...arguments);
    this.x = 0;
    this.y = 0;
    this.size = 12;
  }
  computeBBox() {
    const { x, y, size } = this;
    const half = size / 2;
    return new BBox(x - half, y - half, size, size);
  }
  applyPath(s, moves) {
    const { path } = this;
    let { x, y } = this;
    path.clear();
    for (const { x: mx, y: my, t } of moves) {
      x += mx * s;
      y += my * s;
      if (t === "move") {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }
    path.closePath();
  }
};
__decorateClass([
  ScenePathChangeDetection()
], Marker.prototype, "x", 2);
__decorateClass([
  ScenePathChangeDetection()
], Marker.prototype, "y", 2);
__decorateClass([
  ScenePathChangeDetection({ convertor: Math.abs })
], Marker.prototype, "size", 2);
var Circle = class extends Marker {
  updatePath() {
    const { x, y, path, size } = this;
    const r = size / 2;
    path.clear();
    path.arc(x, y, r, 0, Math.PI * 2);
    path.closePath();
  }
};
Circle.className = "Circle";
var _Cross = class _Cross2 extends Marker {
  updatePath() {
    const s = this.size / 4.2;
    super.applyPath(s, _Cross2.moves);
  }
};
_Cross.className = "Cross";
_Cross.moves = [
  { x: -1, y: 0, t: "move" },
  { x: -1, y: -1 },
  { x: 1, y: -1 },
  { x: 1, y: 1 },
  { x: 1, y: -1 },
  { x: 1, y: 1 },
  { x: -1, y: 1 },
  { x: 1, y: 1 },
  { x: -1, y: 1 },
  { x: -1, y: -1 },
  { x: -1, y: 1 },
  { x: -1, y: -1 }
];
var Cross = _Cross;
var _Diamond = class _Diamond2 extends Marker {
  updatePath() {
    const s = this.size / 2;
    super.applyPath(s, _Diamond2.moves);
  }
};
_Diamond.className = "Diamond";
_Diamond.moves = [
  { x: 0, y: -1, t: "move" },
  { x: 1, y: 1 },
  { x: -1, y: 1 },
  { x: -1, y: -1 },
  { x: 1, y: -1 }
];
var Diamond = _Diamond;
var Heart = class extends Marker {
  rad(degree) {
    return degree / 180 * Math.PI;
  }
  updatePath() {
    const { x, path, size, rad } = this;
    const r = size / 4;
    const y = this.y + r / 2;
    path.clear();
    path.arc(x - r, y - r, r, rad(130), rad(330));
    path.arc(x + r, y - r, r, rad(220), rad(50));
    path.lineTo(x, y + r);
    path.closePath();
  }
};
Heart.className = "Heart";
var _Plus = class _Plus2 extends Marker {
  updatePath() {
    const s = this.size / 3;
    super.applyPath(s, _Plus2.moves);
  }
};
_Plus.className = "Plus";
_Plus.moves = [
  { x: -0.5, y: -0.5, t: "move" },
  { x: 0, y: -1 },
  { x: 1, y: 0 },
  { x: 0, y: 1 },
  { x: 1, y: 0 },
  { x: 0, y: 1 },
  { x: -1, y: 0 },
  { x: 0, y: 1 },
  { x: -1, y: 0 },
  { x: 0, y: -1 },
  { x: -1, y: 0 },
  { x: 0, y: -1 }
];
var Plus = _Plus;
var Square = class extends Marker {
  updatePath() {
    const { path, x, y } = this;
    const hs = this.size / 2;
    path.clear();
    path.moveTo(this.align(x - hs), this.align(y - hs));
    path.lineTo(this.align(x + hs), this.align(y - hs));
    path.lineTo(this.align(x + hs), this.align(y + hs));
    path.lineTo(this.align(x - hs), this.align(y + hs));
    path.closePath();
  }
};
Square.className = "Square";
var _Triangle = class _Triangle2 extends Marker {
  updatePath() {
    const s = this.size * 1.1;
    super.applyPath(s, _Triangle2.moves);
  }
};
_Triangle.className = "Triangle";
_Triangle.moves = [
  { x: 0, y: -0.48, t: "move" },
  { x: 0.5, y: 0.87 },
  { x: -1, y: 0 }
];
var Triangle = _Triangle;
var MARKER_SHAPES = {
  circle: Circle,
  cross: Cross,
  diamond: Diamond,
  heart: Heart,
  plus: Plus,
  square: Square,
  triangle: Triangle
};
var MARKER_SUPPORTED_SHAPES = Object.keys(MARKER_SHAPES);
function isMarkerShape(shape) {
  return typeof shape === "string" && MARKER_SUPPORTED_SHAPES.includes(shape);
}
function getMarker(shape = Square) {
  if (isMarkerShape(shape)) {
    return MARKER_SHAPES[shape];
  }
  if (typeof shape === "function") {
    return shape;
  }
  return Square;
}
var Image = class extends Node {
  constructor(sourceImage) {
    super();
    this.x = 0;
    this.y = 0;
    this.width = 0;
    this.height = 0;
    this.opacity = 1;
    this.sourceImage = sourceImage;
  }
  render(renderCtx) {
    const { ctx, forceRender, stats } = renderCtx;
    if (this.dirty === 0 && !forceRender) {
      if (stats)
        stats.nodesSkipped++;
      return;
    }
    this.computeTransformMatrix();
    this.matrix.toContext(ctx);
    const image = this.sourceImage;
    ctx.globalAlpha = this.opacity;
    ctx.drawImage(image, 0, 0, image.width, image.height, this.x, this.y, this.width, this.height);
    super.render(renderCtx);
  }
};
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Image.prototype, "x", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Image.prototype, "y", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Image.prototype, "width", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Image.prototype, "height", 2);
__decorateClass([
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], Image.prototype, "opacity", 2);
var motion = __spreadValues(__spreadValues({}, fromToMotion_exports), resetMotion_exports);
var isString2 = (v) => typeof v === "string";
var isStringObject = (v) => !!v && Object.hasOwn(v, "toString") && isString2(v.toString());
var isDate2 = (v) => v instanceof Date && !isNaN(+v);
function isDiscrete(value) {
  return isString2(value) || isStringObject(value);
}
function isContinuous(value) {
  const isNumberObject = (v) => !!v && Object.hasOwn(v, "valueOf") && isNumber2(v.valueOf());
  const isDate3 = (v) => v instanceof Date && !isNaN(+v);
  return isNumber2(value) || isNumberObject(value) || isDate3(value);
}
function checkDatum(value, isContinuousScale) {
  if (isContinuousScale && isContinuous(value)) {
    return value;
  } else if (!isContinuousScale) {
    if (!isDiscrete(value)) {
      return String(value);
    }
    return value;
  }
  return void 0;
}
var isNumber2 = (v) => typeof v === "number" && Number.isFinite(v);
var MATCHING_CROSSLINE_TYPE = (property) => {
  return property === "value" ? predicateWithMessage(
    (_, ctx) => ctx.target["type"] === "line",
    (ctx) => ctx.target["type"] === "range" ? `crossLine type 'range' to have a 'range' property instead of 'value'` : `crossLine property 'type' to be 'line'`
  ) : predicateWithMessage(
    (_, ctx) => ctx.target["type"] === "range",
    (ctx) => ctx.target.type === "line" ? `crossLine type 'line' to have a 'value' property instead of 'range'` : `crossLine property 'type' to be 'range'`
  );
};
var validateCrossLineValues = (type, value, range3, scale2) => {
  const lineCrossLine = type === "line" && value !== void 0;
  const rangeCrossLine = type === "range" && range3 !== void 0;
  if (!lineCrossLine && !rangeCrossLine) {
    return true;
  }
  const [start, end] = range3 != null ? range3 : [value, void 0];
  const isContinuous2 = ContinuousScale.is(scale2);
  const validStart = checkDatum(start, isContinuous2) != null && !isNaN(scale2.convert(start));
  const validEnd = checkDatum(end, isContinuous2) != null && !isNaN(scale2.convert(end));
  if (lineCrossLine && validStart || rangeCrossLine && validStart && validEnd) {
    return true;
  }
  const message = [`Expecting crossLine`];
  if (rangeCrossLine) {
    if (!validStart) {
      message.push(`range start ${stringify(start)}`);
    }
    if (!validEnd) {
      message.push(`${!validStart ? "and " : ""}range end ${stringify(end)}`);
    }
  } else {
    message.push(`value ${stringify(start)}`);
  }
  message.push(`to match the axis scale domain.`);
  Logger.warnOnce(message.join(" "));
  return false;
};
var horizontalCrosslineTranslationDirections = {
  top: { xTranslationDirection: 0, yTranslationDirection: -1 },
  bottom: { xTranslationDirection: 0, yTranslationDirection: 1 },
  left: { xTranslationDirection: -1, yTranslationDirection: 0 },
  right: { xTranslationDirection: 1, yTranslationDirection: 0 },
  topLeft: { xTranslationDirection: 1, yTranslationDirection: -1 },
  topRight: { xTranslationDirection: -1, yTranslationDirection: -1 },
  bottomLeft: { xTranslationDirection: 1, yTranslationDirection: 1 },
  bottomRight: { xTranslationDirection: -1, yTranslationDirection: 1 },
  inside: { xTranslationDirection: 0, yTranslationDirection: 0 },
  insideLeft: { xTranslationDirection: 1, yTranslationDirection: 0 },
  insideRight: { xTranslationDirection: -1, yTranslationDirection: 0 },
  insideTop: { xTranslationDirection: 0, yTranslationDirection: 1 },
  insideBottom: { xTranslationDirection: 0, yTranslationDirection: -1 },
  insideTopLeft: { xTranslationDirection: 1, yTranslationDirection: 1 },
  insideBottomLeft: { xTranslationDirection: 1, yTranslationDirection: -1 },
  insideTopRight: { xTranslationDirection: -1, yTranslationDirection: 1 },
  insideBottomRight: { xTranslationDirection: -1, yTranslationDirection: -1 }
};
var verticalCrossLineTranslationDirections = {
  top: { xTranslationDirection: 1, yTranslationDirection: 0 },
  bottom: { xTranslationDirection: -1, yTranslationDirection: 0 },
  left: { xTranslationDirection: 0, yTranslationDirection: -1 },
  right: { xTranslationDirection: 0, yTranslationDirection: 1 },
  topLeft: { xTranslationDirection: -1, yTranslationDirection: -1 },
  topRight: { xTranslationDirection: -1, yTranslationDirection: 1 },
  bottomLeft: { xTranslationDirection: 1, yTranslationDirection: -1 },
  bottomRight: { xTranslationDirection: 1, yTranslationDirection: 1 },
  inside: { xTranslationDirection: 0, yTranslationDirection: 0 },
  insideLeft: { xTranslationDirection: 0, yTranslationDirection: 1 },
  insideRight: { xTranslationDirection: 0, yTranslationDirection: -1 },
  insideTop: { xTranslationDirection: -1, yTranslationDirection: 0 },
  insideBottom: { xTranslationDirection: 1, yTranslationDirection: 0 },
  insideTopLeft: { xTranslationDirection: -1, yTranslationDirection: 1 },
  insideBottomLeft: { xTranslationDirection: 1, yTranslationDirection: 1 },
  insideTopRight: { xTranslationDirection: -1, yTranslationDirection: -1 },
  insideBottomRight: { xTranslationDirection: 1, yTranslationDirection: -1 }
};
function calculateLabelTranslation({
  yDirection,
  padding = 0,
  position = "top",
  bbox
}) {
  const crossLineTranslationDirections = yDirection ? horizontalCrosslineTranslationDirections : verticalCrossLineTranslationDirections;
  const { xTranslationDirection, yTranslationDirection } = crossLineTranslationDirections[position];
  const w = yDirection ? bbox.width : bbox.height;
  const h = yDirection ? bbox.height : bbox.width;
  const xTranslation = xTranslationDirection * (padding + w / 2);
  const yTranslation = yTranslationDirection * (padding + h / 2);
  return {
    xTranslation,
    yTranslation
  };
}
function calculateLabelChartPadding({
  yDirection,
  bbox,
  padding = 0,
  position = "top"
}) {
  const chartPadding = {};
  if (position.startsWith("inside"))
    return chartPadding;
  if (position === "top" && !yDirection) {
    chartPadding.top = padding + bbox.height;
  } else if (position === "bottom" && !yDirection) {
    chartPadding.bottom = padding + bbox.height;
  } else if (position === "left" && yDirection) {
    chartPadding.left = padding + bbox.width;
  } else if (position === "right" && yDirection) {
    chartPadding.right = padding + bbox.width;
  }
  return chartPadding;
}
var POSITION_TOP_COORDINATES = ({ yDirection, xEnd, yStart, yEnd }) => {
  if (yDirection) {
    return { x: xEnd / 2, y: yStart };
  } else {
    return { x: xEnd, y: !isNaN(yEnd) ? (yStart + yEnd) / 2 : yStart };
  }
};
var POSITION_LEFT_COORDINATES = ({ yDirection, xStart, xEnd, yStart, yEnd }) => {
  if (yDirection) {
    return { x: xStart, y: !isNaN(yEnd) ? (yStart + yEnd) / 2 : yStart };
  } else {
    return { x: xEnd / 2, y: yStart };
  }
};
var POSITION_RIGHT_COORDINATES = ({ yDirection, xEnd, yStart, yEnd }) => {
  if (yDirection) {
    return { x: xEnd, y: !isNaN(yEnd) ? (yStart + yEnd) / 2 : yStart };
  } else {
    return { x: xEnd / 2, y: !isNaN(yEnd) ? yEnd : yStart };
  }
};
var POSITION_BOTTOM_COORDINATES = ({ yDirection, xStart, xEnd, yStart, yEnd }) => {
  if (yDirection) {
    return { x: xEnd / 2, y: !isNaN(yEnd) ? yEnd : yStart };
  } else {
    return { x: xStart, y: !isNaN(yEnd) ? (yStart + yEnd) / 2 : yStart };
  }
};
var POSITION_INSIDE_COORDINATES = ({ xEnd, yStart, yEnd }) => {
  return { x: xEnd / 2, y: !isNaN(yEnd) ? (yStart + yEnd) / 2 : yStart };
};
var POSITION_TOP_LEFT_COORDINATES = ({ yDirection, xStart, xEnd, yStart }) => {
  if (yDirection) {
    return { x: xStart / 2, y: yStart };
  } else {
    return { x: xEnd, y: yStart };
  }
};
var POSITION_BOTTOM_LEFT_COORDINATES = ({ yDirection, xStart, yStart, yEnd }) => {
  if (yDirection) {
    return { x: xStart, y: !isNaN(yEnd) ? yEnd : yStart };
  } else {
    return { x: xStart, y: yStart };
  }
};
var POSITION_TOP_RIGHT_COORDINATES = ({ yDirection, xEnd, yStart, yEnd }) => {
  if (yDirection) {
    return { x: xEnd, y: yStart };
  } else {
    return { x: xEnd, y: !isNaN(yEnd) ? yEnd : yStart };
  }
};
var POSITION_BOTTOM_RIGHT_COORDINATES = ({ yDirection, xStart, xEnd, yStart, yEnd }) => {
  if (yDirection) {
    return { x: xEnd, y: !isNaN(yEnd) ? yEnd : yStart };
  } else {
    return { x: xStart, y: !isNaN(yEnd) ? yEnd : yStart };
  }
};
var labelDirectionHandling = {
  top: { c: POSITION_TOP_COORDINATES },
  bottom: { c: POSITION_BOTTOM_COORDINATES },
  left: { c: POSITION_LEFT_COORDINATES },
  right: { c: POSITION_RIGHT_COORDINATES },
  topLeft: { c: POSITION_TOP_LEFT_COORDINATES },
  topRight: { c: POSITION_TOP_RIGHT_COORDINATES },
  bottomLeft: { c: POSITION_BOTTOM_LEFT_COORDINATES },
  bottomRight: { c: POSITION_BOTTOM_RIGHT_COORDINATES },
  inside: { c: POSITION_INSIDE_COORDINATES },
  insideLeft: { c: POSITION_LEFT_COORDINATES },
  insideRight: { c: POSITION_RIGHT_COORDINATES },
  insideTop: { c: POSITION_TOP_COORDINATES },
  insideBottom: { c: POSITION_BOTTOM_COORDINATES },
  insideTopLeft: { c: POSITION_TOP_LEFT_COORDINATES },
  insideBottomLeft: { c: POSITION_BOTTOM_LEFT_COORDINATES },
  insideTopRight: { c: POSITION_TOP_RIGHT_COORDINATES },
  insideBottomRight: { c: POSITION_BOTTOM_RIGHT_COORDINATES }
};
var CROSSLINE_LABEL_POSITION = UNION(
  [
    "top",
    "left",
    "right",
    "bottom",
    "topLeft",
    "topRight",
    "bottomLeft",
    "bottomRight",
    "inside",
    "insideLeft",
    "insideRight",
    "insideTop",
    "insideBottom",
    "insideTopLeft",
    "insideBottomLeft",
    "insideTopRight",
    "insideBottomRight"
  ],
  "crossLine label position"
);
var CartesianCrossLineLabel = class {
  constructor() {
    this.enabled = void 0;
    this.text = void 0;
    this.fontStyle = void 0;
    this.fontWeight = void 0;
    this.fontSize = 14;
    this.fontFamily = "Verdana, sans-serif";
    this.padding = 5;
    this.color = "rgba(87, 87, 87, 1)";
    this.position = void 0;
    this.rotation = void 0;
    this.parallel = void 0;
  }
};
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], CartesianCrossLineLabel.prototype, "enabled", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], CartesianCrossLineLabel.prototype, "text", 2);
__decorateClass([
  Validate(FONT_STYLE, { optional: true })
], CartesianCrossLineLabel.prototype, "fontStyle", 2);
__decorateClass([
  Validate(FONT_WEIGHT, { optional: true })
], CartesianCrossLineLabel.prototype, "fontWeight", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], CartesianCrossLineLabel.prototype, "fontSize", 2);
__decorateClass([
  Validate(STRING)
], CartesianCrossLineLabel.prototype, "fontFamily", 2);
__decorateClass([
  Validate(NUMBER)
], CartesianCrossLineLabel.prototype, "padding", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], CartesianCrossLineLabel.prototype, "color", 2);
__decorateClass([
  Validate(CROSSLINE_LABEL_POSITION, { optional: true })
], CartesianCrossLineLabel.prototype, "position", 2);
__decorateClass([
  Validate(DEGREE, { optional: true })
], CartesianCrossLineLabel.prototype, "rotation", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], CartesianCrossLineLabel.prototype, "parallel", 2);
var _CartesianCrossLine = class _CartesianCrossLine2 {
  constructor() {
    this.id = createId(this);
    this.enabled = void 0;
    this.type = void 0;
    this.range = void 0;
    this.value = void 0;
    this.fill = void 0;
    this.fillOpacity = void 0;
    this.stroke = void 0;
    this.strokeWidth = void 0;
    this.strokeOpacity = void 0;
    this.lineDash = void 0;
    this.label = new CartesianCrossLineLabel();
    this.scale = void 0;
    this.clippedRange = [-Infinity, Infinity];
    this.gridLength = 0;
    this.sideFlag = -1;
    this.parallelFlipRotation = 0;
    this.regularFlipRotation = 0;
    this.direction = "x";
    this.group = new Group({ name: `${this.id}`, layer: true, zIndex: _CartesianCrossLine2.LINE_LAYER_ZINDEX });
    this.labelGroup = new Group({ name: `${this.id}`, layer: true, zIndex: _CartesianCrossLine2.LABEL_LAYER_ZINDEX });
    this.crossLineRange = new Range();
    this.crossLineLabel = new Text();
    this.labelPoint = void 0;
    this.data = [];
    this.startLine = false;
    this.endLine = false;
    this.isRange = false;
    const { group: group2, labelGroup, crossLineRange, crossLineLabel } = this;
    group2.append(crossLineRange);
    labelGroup.append(crossLineLabel);
    crossLineRange.pointerEvents = 1;
  }
  update(visible) {
    const { enabled, data, type, value, range: range3, scale: scale2 } = this;
    if (!type || !scale2 || !enabled || !visible || !validateCrossLineValues(type, value, range3, scale2) || data.length === 0) {
      this.group.visible = false;
      this.labelGroup.visible = false;
      return;
    }
    this.group.visible = visible;
    this.labelGroup.visible = visible;
    this.group.zIndex = this.getZIndex(this.isRange);
    this.updateNodes();
  }
  calculateLayout(visible, reversedAxis) {
    if (!visible) {
      return;
    }
    const dataCreated = this.createNodeData(reversedAxis);
    if (!dataCreated) {
      return;
    }
    const { sideFlag, gridLength, data } = this;
    const boxes = [];
    const x1 = 0;
    const x2 = sideFlag * gridLength;
    const y1 = data[0];
    const y2 = data[1];
    const crossLineBox = new BBox(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
    boxes.push(crossLineBox);
    const labelBox = this.computeLabelBBox();
    if (labelBox) {
      boxes.push(labelBox);
    }
    return BBox.merge(boxes);
  }
  updateNodes() {
    this.updateRangeNode();
    if (this.label.enabled) {
      this.updateLabel();
      this.positionLabel();
    }
  }
  createNodeData(reversedAxis) {
    var _a, _b, _c;
    const {
      scale: scale2,
      gridLength,
      sideFlag,
      direction,
      label: { position = "top" },
      clippedRange,
      strokeWidth = 0
    } = this;
    this.data = [];
    if (!scale2) {
      return false;
    }
    const bandwidth = (_a = scale2.bandwidth) != null ? _a : 0;
    const step = (_b = scale2.step) != null ? _b : 0;
    const padding = (reversedAxis ? -1 : 1) * (scale2 instanceof BandScale ? (step - bandwidth) / 2 : 0);
    const [xStart, xEnd] = [0, sideFlag * gridLength];
    let [yStart, yEnd] = this.getRange();
    let [clampedYStart, clampedYEnd] = [
      Number(scale2.convert(yStart, { clampMode: "clamped" })) - padding,
      scale2.convert(yEnd, { clampMode: "clamped" }) + bandwidth + padding
    ];
    clampedYStart = clampArray(clampedYStart, clippedRange);
    clampedYEnd = clampArray(clampedYEnd, clippedRange);
    [yStart, yEnd] = [Number(scale2.convert(yStart)), scale2.convert(yEnd) + bandwidth];
    const validRange = (yStart === clampedYStart || yEnd === clampedYEnd || clampedYStart !== clampedYEnd) && Math.abs(clampedYEnd - clampedYStart) > 0;
    if (validRange && clampedYStart > clampedYEnd) {
      [clampedYStart, clampedYEnd] = [clampedYEnd, clampedYStart];
      [yStart, yEnd] = [yEnd, yStart];
    }
    if (yStart - padding >= clampedYStart)
      yStart -= padding;
    if (yEnd + padding <= clampedYEnd)
      yEnd += padding;
    this.isRange = validRange;
    this.startLine = strokeWidth > 0 && yStart >= clampedYStart && yStart <= clampedYStart + padding;
    this.endLine = strokeWidth > 0 && yEnd >= clampedYEnd - bandwidth - padding && yEnd <= clampedYEnd;
    if (!validRange && !this.startLine && !this.endLine) {
      return false;
    }
    this.data = [clampedYStart, clampedYEnd];
    if (this.label.enabled) {
      const yDirection = direction === "y";
      const { c = POSITION_TOP_COORDINATES } = (_c = labelDirectionHandling[position]) != null ? _c : {};
      const { x: labelX, y: labelY } = c({
        yDirection,
        xStart,
        xEnd,
        yStart: clampedYStart,
        yEnd: clampedYEnd
      });
      this.labelPoint = {
        x: labelX,
        y: labelY
      };
    }
    return true;
  }
  updateRangeNode() {
    var _a;
    const {
      crossLineRange,
      sideFlag,
      gridLength,
      data,
      startLine,
      endLine,
      isRange,
      fill,
      fillOpacity,
      stroke,
      strokeWidth,
      lineDash
    } = this;
    crossLineRange.x1 = 0;
    crossLineRange.x2 = sideFlag * gridLength;
    crossLineRange.y1 = data[0];
    crossLineRange.y2 = data[1];
    crossLineRange.startLine = startLine;
    crossLineRange.endLine = endLine;
    crossLineRange.isRange = isRange;
    crossLineRange.fill = fill;
    crossLineRange.fillOpacity = fillOpacity != null ? fillOpacity : 1;
    crossLineRange.stroke = stroke;
    crossLineRange.strokeWidth = strokeWidth != null ? strokeWidth : 1;
    crossLineRange.strokeOpacity = (_a = this.strokeOpacity) != null ? _a : 1;
    crossLineRange.lineDash = lineDash;
  }
  updateLabel() {
    const { crossLineLabel, label } = this;
    if (!label.text) {
      return;
    }
    crossLineLabel.fontStyle = label.fontStyle;
    crossLineLabel.fontWeight = label.fontWeight;
    crossLineLabel.fontSize = label.fontSize;
    crossLineLabel.fontFamily = label.fontFamily;
    crossLineLabel.fill = label.color;
    crossLineLabel.text = label.text;
  }
  positionLabel() {
    const {
      crossLineLabel,
      labelPoint: { x = void 0, y = void 0 } = {},
      label: { parallel, rotation, position = "top", padding = 0 },
      direction,
      parallelFlipRotation,
      regularFlipRotation
    } = this;
    if (x === void 0 || y === void 0) {
      return;
    }
    const { defaultRotation, configuredRotation } = calculateLabelRotation({
      rotation,
      parallel,
      regularFlipRotation,
      parallelFlipRotation
    });
    crossLineLabel.rotation = defaultRotation + configuredRotation;
    crossLineLabel.textBaseline = "middle";
    crossLineLabel.textAlign = "center";
    const bbox = crossLineLabel.computeTransformedBBox();
    if (!bbox) {
      return;
    }
    const yDirection = direction === "y";
    const { xTranslation, yTranslation } = calculateLabelTranslation({
      yDirection,
      padding,
      position,
      bbox
    });
    crossLineLabel.translationX = x + xTranslation;
    crossLineLabel.translationY = y + yTranslation;
  }
  getZIndex(isRange = false) {
    if (isRange) {
      return _CartesianCrossLine2.RANGE_LAYER_ZINDEX;
    }
    return _CartesianCrossLine2.LINE_LAYER_ZINDEX;
  }
  getRange() {
    var _a;
    const { value, range: range3, scale: scale2 } = this;
    const isContinuous2 = ContinuousScale.is(scale2);
    const start = (_a = range3 == null ? void 0 : range3[0]) != null ? _a : value;
    let end = range3 == null ? void 0 : range3[1];
    if (!isContinuous2 && end === void 0) {
      end = start;
    }
    if (isContinuous2 && start === end) {
      end = void 0;
    }
    return [start, end];
  }
  computeLabelBBox() {
    const { label } = this;
    if (!label.enabled) {
      return void 0;
    }
    const tempText = new Text();
    tempText.fontFamily = label.fontFamily;
    tempText.fontSize = label.fontSize;
    tempText.fontStyle = label.fontStyle;
    tempText.fontWeight = label.fontWeight;
    tempText.text = label.text;
    const {
      labelPoint: { x = void 0, y = void 0 } = {},
      label: { parallel, rotation, position = "top", padding = 0 },
      direction,
      parallelFlipRotation,
      regularFlipRotation
    } = this;
    if (x === void 0 || y === void 0) {
      return void 0;
    }
    const { configuredRotation } = calculateLabelRotation({
      rotation,
      parallel,
      regularFlipRotation,
      parallelFlipRotation
    });
    tempText.rotation = configuredRotation;
    tempText.textBaseline = "middle";
    tempText.textAlign = "center";
    const bbox = tempText.computeTransformedBBox();
    if (!bbox) {
      return void 0;
    }
    const yDirection = direction === "y";
    const { xTranslation, yTranslation } = calculateLabelTranslation({
      yDirection,
      padding,
      position,
      bbox
    });
    tempText.translationX = x + xTranslation;
    tempText.translationY = y + yTranslation;
    return tempText.computeTransformedBBox();
  }
  calculatePadding(padding) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const {
      isRange,
      startLine,
      endLine,
      direction,
      label: { padding: labelPadding = 0, position = "top" }
    } = this;
    if (!isRange && !startLine && !endLine) {
      return;
    }
    const crossLineLabelBBox = this.computeLabelBBox();
    const labelX = crossLineLabelBBox == null ? void 0 : crossLineLabelBBox.x;
    const labelY = crossLineLabelBBox == null ? void 0 : crossLineLabelBBox.y;
    if (!crossLineLabelBBox || labelX == void 0 || labelY == void 0) {
      return;
    }
    const chartPadding = calculateLabelChartPadding({
      yDirection: direction === "y",
      padding: labelPadding,
      position,
      bbox: crossLineLabelBBox
    });
    padding.left = Math.max((_a = padding.left) != null ? _a : 0, (_b = chartPadding.left) != null ? _b : 0);
    padding.right = Math.max((_c = padding.right) != null ? _c : 0, (_d = chartPadding.right) != null ? _d : 0);
    padding.top = Math.max((_e = padding.top) != null ? _e : 0, (_f = chartPadding.top) != null ? _f : 0);
    padding.bottom = Math.max((_g = padding.bottom) != null ? _g : 0, (_h = chartPadding.bottom) != null ? _h : 0);
  }
};
_CartesianCrossLine.LINE_LAYER_ZINDEX = 8;
_CartesianCrossLine.RANGE_LAYER_ZINDEX = 3;
_CartesianCrossLine.LABEL_LAYER_ZINDEX = 7;
_CartesianCrossLine.className = "CrossLine";
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], _CartesianCrossLine.prototype, "enabled", 2);
__decorateClass([
  Validate(UNION(["range", "line"], "a crossLine type"), { optional: true })
], _CartesianCrossLine.prototype, "type", 2);
__decorateClass([
  Validate(AND(MATCHING_CROSSLINE_TYPE("range"), ARRAY.restrict({ length: 2 })), {
    optional: true
  })
], _CartesianCrossLine.prototype, "range", 2);
__decorateClass([
  Validate(MATCHING_CROSSLINE_TYPE("value"), { optional: true })
], _CartesianCrossLine.prototype, "value", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], _CartesianCrossLine.prototype, "fill", 2);
__decorateClass([
  Validate(RATIO, { optional: true })
], _CartesianCrossLine.prototype, "fillOpacity", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], _CartesianCrossLine.prototype, "stroke", 2);
__decorateClass([
  Validate(NUMBER, { optional: true })
], _CartesianCrossLine.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO, { optional: true })
], _CartesianCrossLine.prototype, "strokeOpacity", 2);
__decorateClass([
  Validate(LINE_DASH, { optional: true })
], _CartesianCrossLine.prototype, "lineDash", 2);
var CartesianCrossLine = _CartesianCrossLine;
var ModuleMap = class {
  constructor() {
    this.moduleMap = /* @__PURE__ */ new Map();
  }
  addModule(module2, moduleFactory) {
    if (this.moduleMap.has(module2.optionsKey)) {
      throw new Error(`AG Charts - module already initialised: ${module2.optionsKey}`);
    }
    this.moduleMap.set(module2.optionsKey, moduleFactory(module2));
  }
  removeModule(module2) {
    var _a;
    const moduleKey = isString(module2) ? module2 : module2.optionsKey;
    (_a = this.moduleMap.get(moduleKey)) == null ? void 0 : _a.destroy();
    this.moduleMap.delete(moduleKey);
  }
  isModuleEnabled(module2) {
    return this.moduleMap.has(isString(module2) ? module2 : module2.optionsKey);
  }
  getModule(module2) {
    return this.moduleMap.get(isString(module2) ? module2 : module2.optionsKey);
  }
  get modules() {
    return this.moduleMap.values();
  }
  mapValues(callback) {
    return Array.from(this.moduleMap.values()).map(callback);
  }
  destroy() {
    for (const optionsKey of this.moduleMap.keys()) {
      this.removeModule({ optionsKey });
    }
  }
};
var StateMachine = class {
  constructor(initialState, states, preTransitionCb) {
    this.states = states;
    this.preTransitionCb = preTransitionCb;
    this.debug = Debug.create(true, "animation");
    this.state = initialState;
    this.debug(`%c${this.constructor.name} | init -> ${initialState}`, "color: green");
  }
  transition(event, data) {
    var _a, _b;
    const currentStateConfig = this.states[this.state];
    const destinationTransition = currentStateConfig == null ? void 0 : currentStateConfig[event];
    if (!destinationTransition) {
      this.debug(`%c${this.constructor.name} | ${this.state} -> ${event} -> ${this.state}`, "color: grey");
      return;
    }
    let destinationState = this.state;
    if (typeof destinationTransition === "string") {
      destinationState = destinationTransition;
    } else if (typeof destinationTransition === "object") {
      destinationState = destinationTransition.target;
    }
    this.debug(`%c${this.constructor.name} | ${this.state} -> ${event} -> ${destinationState}`, "color: green");
    (_a = this.preTransitionCb) == null ? void 0 : _a.call(this, this.state, destinationState);
    this.state = destinationState;
    if (typeof destinationTransition === "function") {
      destinationTransition(data);
    } else if (typeof destinationTransition === "object") {
      (_b = destinationTransition.action) == null ? void 0 : _b.call(destinationTransition, data);
    }
    return this.state;
  }
};
var identity = (x) => x;
var _LogScale = class _LogScale2 extends ContinuousScale {
  constructor() {
    super([1, 10], [0, 1]);
    this.type = "log";
    this.base = 10;
    this.baseLog = identity;
    this.basePow = identity;
    this.log = (x) => {
      const start = Math.min(this.domain[0], this.domain[1]);
      return start >= 0 ? this.baseLog(x) : -this.baseLog(-x);
    };
    this.pow = (x) => {
      const start = Math.min(this.domain[0], this.domain[1]);
      return start >= 0 ? this.basePow(x) : -this.basePow(-x);
    };
    this.defaultClampMode = "clamped";
  }
  toDomain(d) {
    return d;
  }
  transform(x) {
    const start = Math.min(this.domain[0], this.domain[1]);
    return start >= 0 ? Math.log(x) : -Math.log(-x);
  }
  transformInvert(x) {
    const start = Math.min(this.domain[0], this.domain[1]);
    return start >= 0 ? Math.exp(x) : -Math.exp(-x);
  }
  refresh() {
    if (this.base <= 0) {
      this.base = 0;
      Logger.warnOnce("expecting a finite Number greater than to 0");
    }
    super.refresh();
  }
  update() {
    if (!this.domain || this.domain.length < 2) {
      return;
    }
    this.updateLogFn();
    this.updatePowFn();
    if (this.nice) {
      this.updateNiceDomain();
    }
  }
  updateLogFn() {
    const { base } = this;
    let log;
    if (base === 10) {
      log = Math.log10;
    } else if (base === Math.E) {
      log = Math.log;
    } else if (base === 2) {
      log = Math.log2;
    } else {
      const logBase = Math.log(base);
      log = (x) => Math.log(x) / logBase;
    }
    this.baseLog = log;
  }
  updatePowFn() {
    const { base } = this;
    let pow;
    if (base === 10) {
      pow = _LogScale2.pow10;
    } else if (base === Math.E) {
      pow = Math.exp;
    } else {
      pow = (x) => Math.pow(base, x);
    }
    this.basePow = pow;
  }
  updateNiceDomain() {
    const [d0, d1] = this.domain;
    const roundStart = d0 > d1 ? Math.ceil : Math.floor;
    const roundStop = d1 < d0 ? Math.floor : Math.ceil;
    const n0 = this.pow(roundStart(this.log(d0)));
    const n1 = this.pow(roundStop(this.log(d1)));
    this.niceDomain = [n0, n1];
  }
  static pow10(x) {
    return x >= 0 ? Math.pow(10, x) : 1 / Math.pow(10, -x);
  }
  ticks() {
    var _a;
    const count2 = (_a = this.tickCount) != null ? _a : 10;
    if (!this.domain || this.domain.length < 2 || count2 < 1) {
      return [];
    }
    this.refresh();
    const base = this.base;
    const [d0, d1] = this.getDomain();
    const start = Math.min(d0, d1);
    const stop = Math.max(d0, d1);
    let p0 = this.log(start);
    let p1 = this.log(stop);
    if (this.interval) {
      const step = Math.abs(this.interval);
      const absDiff = Math.abs(p1 - p0);
      let ticks2 = range(p0, p1, Math.min(absDiff, step));
      ticks2 = createNumericTicks(
        ticks2.fractionDigits,
        ticks2.map((x) => this.pow(x)).filter((t) => t >= start && t <= stop)
      );
      if (!this.isDenseInterval({ start, stop, interval: step, count: ticks2.length })) {
        return ticks2;
      }
    }
    const isBaseInteger = base % 1 === 0;
    const isDiffLarge = p1 - p0 >= count2;
    if (!isBaseInteger || isDiffLarge) {
      let ticks2 = ticks_default(p0, p1, Math.min(p1 - p0, count2));
      ticks2 = createNumericTicks(
        ticks2.fractionDigits,
        ticks2.map((x) => this.pow(x))
      );
      return ticks2;
    }
    const ticks = [];
    const isPositive = start > 0;
    p0 = Math.floor(p0) - 1;
    p1 = Math.round(p1) + 1;
    const min = Math.min(...this.range);
    const max = Math.max(...this.range);
    const availableSpacing = (max - min) / count2;
    let lastTickPosition = Infinity;
    for (let p = p0; p <= p1; p++) {
      const nextMagnitudeTickPosition = this.convert(this.pow(p + 1));
      for (let k = 1; k < base; k++) {
        const q = isPositive ? k : base - k + 1;
        const t = this.pow(p) * q;
        const tickPosition = this.convert(t);
        const prevSpacing = Math.abs(lastTickPosition - tickPosition);
        const nextSpacing = Math.abs(tickPosition - nextMagnitudeTickPosition);
        const fits = prevSpacing >= availableSpacing && nextSpacing >= availableSpacing;
        if (t >= start && t <= stop && (k === 1 || fits)) {
          ticks.push(t);
          lastTickPosition = tickPosition;
        }
      }
    }
    return ticks;
  }
  tickFormat({
    count: count2,
    ticks,
    specifier
  }) {
    const { base } = this;
    if (specifier == null) {
      specifier = base === 10 ? ".0e" : ",";
    }
    if (typeof specifier === "string") {
      specifier = format(specifier);
    }
    if (count2 === Infinity) {
      return specifier;
    }
    if (ticks == null) {
      this.ticks();
    }
    return (d) => {
      return specifier(d);
    };
  }
};
__decorateClass([
  Invalidating
], _LogScale.prototype, "base", 2);
var LogScale = _LogScale;
var CONSTANTS = {
  periods: ["AM", "PM"],
  days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
  shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
  months: [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
  ],
  shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
};
function dayOfYear(date, startOfYear = new Date(date.getFullYear(), 0, 1)) {
  const startOffset = date.getTimezoneOffset() - startOfYear.getTimezoneOffset();
  const timeDiff = date.getTime() - startOfYear.getTime() + startOffset * 6e4;
  const timeOneDay = 36e5 * 24;
  return Math.floor(timeDiff / timeOneDay);
}
function weekOfYear(date, startDay) {
  const startOfYear = new Date(date.getFullYear(), 0, 1);
  const startOfYearDay = startOfYear.getDay();
  const firstWeekStartOffset = (startDay - startOfYearDay + 7) % 7;
  const startOffset = new Date(date.getFullYear(), 0, firstWeekStartOffset + 1);
  if (startOffset <= date) {
    return Math.floor(dayOfYear(date, startOffset) / 7) + 1;
  }
  return 0;
}
var SUNDAY = 0;
var MONDAY = 1;
var THURSDAY = 4;
function isoWeekOfYear(date, year2 = date.getFullYear()) {
  const firstOfYear = new Date(year2, 0, 1);
  const firstOfYearDay = firstOfYear.getDay();
  const firstThursdayOffset = (THURSDAY - firstOfYearDay + 7) % 7;
  const startOffset = new Date(year2, 0, firstThursdayOffset - (THURSDAY - MONDAY) + 1);
  if (startOffset <= date) {
    return Math.floor(dayOfYear(date, startOffset) / 7) + 1;
  }
  return isoWeekOfYear(date, year2 - 1);
}
function timezone(date) {
  const offset4 = date.getTimezoneOffset();
  const unsignedOffset = Math.abs(offset4);
  const sign = offset4 > 0 ? "-" : "+";
  return `${sign}${pad(Math.floor(unsignedOffset / 60), 2, "0")}${pad(Math.floor(unsignedOffset % 60), 2, "0")}`;
}
var FORMATTERS = {
  a: (d) => CONSTANTS.shortDays[d.getDay()],
  A: (d) => CONSTANTS.days[d.getDay()],
  b: (d) => CONSTANTS.shortMonths[d.getMonth()],
  B: (d) => CONSTANTS.months[d.getMonth()],
  c: "%x, %X",
  d: (d, p) => pad(d.getDate(), 2, p != null ? p : "0"),
  e: "%_d",
  f: (d, p) => pad(d.getMilliseconds() * 1e3, 6, p != null ? p : "0"),
  H: (d, p) => pad(d.getHours(), 2, p != null ? p : "0"),
  I: (d, p) => {
    const hours = d.getHours() % 12;
    return hours === 0 ? "12" : pad(hours, 2, p != null ? p : "0");
  },
  j: (d, p) => pad(dayOfYear(d) + 1, 3, p != null ? p : "0"),
  m: (d, p) => pad(d.getMonth() + 1, 2, p != null ? p : "0"),
  M: (d, p) => pad(d.getMinutes(), 2, p != null ? p : "0"),
  L: (d, p) => pad(d.getMilliseconds(), 3, p != null ? p : "0"),
  p: (d) => d.getHours() < 12 ? "AM" : "PM",
  Q: (d) => String(d.getTime()),
  s: (d) => String(Math.floor(d.getTime() / 1e3)),
  S: (d, p) => pad(d.getSeconds(), 2, p != null ? p : "0"),
  u: (d) => {
    let day2 = d.getDay();
    if (day2 < 1)
      day2 += 7;
    return String(day2 % 7);
  },
  U: (d, p) => pad(weekOfYear(d, SUNDAY), 2, p != null ? p : "0"),
  V: (d, p) => pad(isoWeekOfYear(d), 2, p != null ? p : "0"),
  w: (d, p) => pad(d.getDay(), 2, p != null ? p : "0"),
  W: (d, p) => pad(weekOfYear(d, MONDAY), 2, p != null ? p : "0"),
  x: "%-m/%-d/%Y",
  X: "%-I:%M:%S %p",
  y: (d, p) => pad(d.getFullYear() % 100, 2, p != null ? p : "0"),
  Y: (d, p) => pad(d.getFullYear(), 4, p != null ? p : "0"),
  Z: (d) => timezone(d),
  "%": () => "%"
};
var PADS = {
  _: " ",
  "0": "0",
  "-": ""
};
function pad(value, size, padChar) {
  const output = String(Math.floor(value));
  if (output.length >= size) {
    return output;
  }
  return `${padChar.repeat(size - output.length)}${output}`;
}
function buildFormatter(formatString) {
  const formatParts = [];
  while (formatString.length > 0) {
    let nextEscapeIdx = formatString.indexOf("%");
    if (nextEscapeIdx !== 0) {
      const literalPart = nextEscapeIdx > 0 ? formatString.substring(0, nextEscapeIdx) : formatString;
      formatParts.push(literalPart);
    }
    if (nextEscapeIdx < 0)
      break;
    const maybePadSpecifier = formatString[nextEscapeIdx + 1];
    const maybePad = PADS[maybePadSpecifier];
    if (maybePad != null) {
      nextEscapeIdx++;
    }
    const maybeFormatterSpecifier = formatString[nextEscapeIdx + 1];
    const maybeFormatter = FORMATTERS[maybeFormatterSpecifier];
    if (typeof maybeFormatter === "function") {
      formatParts.push([maybeFormatter, maybePad]);
    } else if (typeof maybeFormatter === "string") {
      const formatter = buildFormatter(maybeFormatter);
      formatParts.push([formatter, maybePad]);
    } else {
      formatParts.push(`${maybePad != null ? maybePad : ""}${maybeFormatterSpecifier}`);
    }
    formatString = formatString.substring(nextEscapeIdx + 2);
  }
  return (dateTime) => {
    const dateTimeAsDate = typeof dateTime === "number" ? new Date(dateTime) : dateTime;
    return formatParts.map((c) => typeof c === "string" ? c : c[0](dateTimeAsDate, c[1])).join("");
  };
}
var formatStrings = {
  [
    0
    /* MILLISECOND */
  ]: ".%L",
  [
    1
    /* SECOND */
  ]: ":%S",
  [
    2
    /* MINUTE */
  ]: "%I:%M",
  [
    3
    /* HOUR */
  ]: "%I %p",
  [
    4
    /* WEEK_DAY */
  ]: "%a",
  [
    5
    /* SHORT_MONTH */
  ]: "%b %d",
  [
    6
    /* MONTH */
  ]: "%B",
  [
    7
    /* SHORT_YEAR */
  ]: "%y",
  [
    8
    /* YEAR */
  ]: "%Y"
};
function toNumber(x) {
  return x instanceof Date ? x.getTime() : x;
}
var TimeScale = class extends ContinuousScale {
  constructor() {
    super([new Date(2022, 11, 7), new Date(2022, 11, 8)], [0, 1]);
    this.type = "time";
    this.year = year_default;
    this.month = month_default;
    this.week = week_default;
    this.day = day_default;
    this.hour = hour_default;
    this.minute = minute_default;
    this.second = second_default;
    this.millisecond = millisecond_default;
    this.tickIntervals = [
      [this.second, 1, durationSecond],
      [this.second, 5, 5 * durationSecond],
      [this.second, 15, 15 * durationSecond],
      [this.second, 30, 30 * durationSecond],
      [this.minute, 1, durationMinute],
      [this.minute, 5, 5 * durationMinute],
      [this.minute, 15, 15 * durationMinute],
      [this.minute, 30, 30 * durationMinute],
      [this.hour, 1, durationHour],
      [this.hour, 3, 3 * durationHour],
      [this.hour, 6, 6 * durationHour],
      [this.hour, 12, 12 * durationHour],
      [this.day, 1, durationDay],
      [this.day, 2, 2 * durationDay],
      [this.week, 1, durationWeek],
      [this.week, 2, 2 * durationWeek],
      [this.week, 3, 3 * durationWeek],
      [this.month, 1, durationMonth],
      [this.month, 2, 2 * durationMonth],
      [this.month, 3, 3 * durationMonth],
      [this.month, 4, 4 * durationMonth],
      [this.month, 6, 6 * durationMonth],
      [this.year, 1, durationYear]
    ];
  }
  toDomain(d) {
    return new Date(d);
  }
  calculateDefaultTickFormat(ticks = []) {
    let defaultTimeFormat = 8;
    const updateFormat = (format2) => {
      if (format2 < defaultTimeFormat) {
        defaultTimeFormat = format2;
      }
    };
    for (const value of ticks) {
      const format2 = this.getLowestGranularityFormat(value);
      updateFormat(format2);
    }
    const firstTick = toNumber(ticks[0]);
    const lastTick = toNumber(ticks[ticks.length - 1]);
    const startYear = new Date(firstTick).getFullYear();
    const stopYear = new Date(lastTick).getFullYear();
    const yearChange = stopYear - startYear > 0;
    return this.buildFormatString(defaultTimeFormat, yearChange);
  }
  buildFormatString(defaultTimeFormat, yearChange) {
    let formatStringArray = [formatStrings[defaultTimeFormat]];
    let timeEndIndex = 0;
    const domain = this.getDomain();
    const start = Math.min(...domain.map(toNumber));
    const stop = Math.max(...domain.map(toNumber));
    const extent2 = stop - start;
    switch (defaultTimeFormat) {
      case 1:
        if (extent2 / durationMinute > 1) {
          formatStringArray.push(formatStrings[
            2
            /* MINUTE */
          ]);
        }
      case 2:
        if (extent2 / durationHour > 1) {
          formatStringArray.push(formatStrings[
            3
            /* HOUR */
          ]);
        }
      case 3:
        timeEndIndex = formatStringArray.length;
        if (extent2 / durationDay > 1) {
          formatStringArray.push(formatStrings[
            4
            /* WEEK_DAY */
          ]);
        }
      case 4:
        if (extent2 / durationWeek > 1 || yearChange) {
          const weekDayIndex = formatStringArray.indexOf(formatStrings[
            4
            /* WEEK_DAY */
          ]);
          if (weekDayIndex > -1) {
            formatStringArray.splice(weekDayIndex, 1, formatStrings[
              5
              /* SHORT_MONTH */
            ]);
          }
        }
      case 5:
      case 6:
        if (extent2 / durationYear > 1 || yearChange) {
          formatStringArray.push(formatStrings[
            8
            /* YEAR */
          ]);
        }
      default:
        break;
    }
    if (timeEndIndex < formatStringArray.length) {
      formatStringArray = [
        ...formatStringArray.slice(0, timeEndIndex),
        formatStringArray.slice(timeEndIndex).join(" ")
      ];
    }
    if (timeEndIndex > 0) {
      formatStringArray = [
        ...formatStringArray.slice(0, timeEndIndex).reverse(),
        ...formatStringArray.slice(timeEndIndex)
      ];
      if (timeEndIndex < formatStringArray.length) {
        formatStringArray.splice(timeEndIndex, 0, " ");
      }
    }
    return formatStringArray.join("");
  }
  getLowestGranularityFormat(value) {
    if (this.second.floor(value) < value) {
      return 0;
    } else if (this.minute.floor(value) < value) {
      return 1;
    } else if (this.hour.floor(value) < value) {
      return 2;
    } else if (this.day.floor(value) < value) {
      return 3;
    } else if (this.month.floor(value) < value) {
      if (this.week.floor(value) < value) {
        return 4;
      }
      return 5;
    } else if (this.year.floor(value) < value) {
      return 6;
    }
    return 8;
  }
  defaultTickFormat(ticks) {
    const formatString = this.calculateDefaultTickFormat(ticks);
    return (date) => buildFormatter(formatString)(date);
  }
  /**
   * @param options Tick interval options.
   * @param options.start The start time (timestamp).
   * @param options.stop The end time (timestamp).
   * @param options.count Number of intervals between ticks.
   */
  getTickInterval({
    start,
    stop,
    count: count2,
    minCount,
    maxCount
  }) {
    const { tickIntervals } = this;
    let countableTimeInterval;
    let step;
    const tickCount = count2 != null ? count2 : ContinuousScale.defaultTickCount;
    const target = Math.abs(stop - start) / Math.max(tickCount, 1);
    let i = 0;
    while (i < tickIntervals.length && target > tickIntervals[i][2]) {
      i++;
    }
    if (i === 0) {
      step = Math.max(tickStep(start, stop, tickCount, minCount, maxCount), 1);
      countableTimeInterval = this.millisecond;
    } else if (i === tickIntervals.length) {
      const y0 = start / durationYear;
      const y1 = stop / durationYear;
      step = tickStep(y0, y1, tickCount, minCount, maxCount);
      countableTimeInterval = this.year;
    } else {
      const diff0 = target - tickIntervals[i - 1][2];
      const diff1 = tickIntervals[i][2] - target;
      const index = diff0 < diff1 ? i - 1 : i;
      [countableTimeInterval, step] = tickIntervals[index];
    }
    return countableTimeInterval.every(step);
  }
  invert(y) {
    return new Date(super.invert(y));
  }
  /**
   * Returns uniformly-spaced dates that represent the scale's domain.
   */
  ticks() {
    if (!this.domain || this.domain.length < 2) {
      return [];
    }
    this.refresh();
    const [t0, t1] = this.getDomain().map(toNumber);
    const start = Math.min(t0, t1);
    const stop = Math.max(t0, t1);
    if (this.interval !== void 0) {
      return this.getTicksForInterval({ start, stop });
    }
    if (this.nice) {
      const { tickCount } = this;
      if (tickCount === 2) {
        return this.niceDomain;
      }
      if (tickCount === 1) {
        return this.niceDomain.slice(0, 1);
      }
    }
    return this.getDefaultTicks({ start, stop });
  }
  getDefaultTicks({ start, stop }) {
    const t = this.getTickInterval({
      start,
      stop,
      count: this.tickCount,
      minCount: this.minTickCount,
      maxCount: this.maxTickCount
    });
    return t ? t.range(new Date(start), new Date(stop)) : [];
  }
  getTicksForInterval({ start, stop }) {
    const { interval, tickIntervals } = this;
    if (!interval) {
      return [];
    }
    if (interval instanceof TimeInterval) {
      const ticks2 = interval.range(new Date(start), new Date(stop));
      if (this.isDenseInterval({ start, stop, interval, count: ticks2.length })) {
        return this.getDefaultTicks({ start, stop });
      }
      return ticks2;
    }
    const absInterval = Math.abs(interval);
    if (this.isDenseInterval({ start, stop, interval: absInterval })) {
      return this.getDefaultTicks({ start, stop });
    }
    const reversedInterval = [...tickIntervals];
    reversedInterval.reverse();
    const timeInterval = reversedInterval.find((tickInterval) => absInterval % tickInterval[2] === 0);
    if (timeInterval) {
      const i = timeInterval[0].every(absInterval / (timeInterval[2] / timeInterval[1]));
      return i.range(new Date(start), new Date(stop));
    }
    let date = new Date(start);
    const stopDate = new Date(stop);
    const ticks = [];
    while (date <= stopDate) {
      ticks.push(date);
      date = new Date(date);
      date.setMilliseconds(date.getMilliseconds() + absInterval);
    }
    return ticks;
  }
  /**
   * Returns a time format function suitable for displaying tick values.
   * @param specifier If the specifier string is provided, this method is equivalent to
   * the {@link TimeLocaleObject.format} method.
   * If no specifier is provided, this method returns the default time format function.
   */
  tickFormat({ ticks, specifier }) {
    return specifier == void 0 ? this.defaultTickFormat(ticks) : buildFormatter(specifier);
  }
  update() {
    if (!this.domain || this.domain.length < 2) {
      return;
    }
    if (this.nice) {
      this.updateNiceDomain();
    }
  }
  /**
   * Extends the domain so that it starts and ends on nice round values.
   * This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value.
   */
  updateNiceDomain() {
    const maxAttempts = 4;
    let [d0, d1] = this.domain;
    for (let i = 0; i < maxAttempts; i++) {
      this.updateNiceDomainIteration(d0, d1);
      const [n0, n1] = this.niceDomain;
      if (toNumber(d0) === toNumber(n0) && toNumber(d1) === toNumber(n1)) {
        break;
      }
      d0 = n0;
      d1 = n1;
    }
  }
  updateNiceDomainIteration(d0, d1) {
    const start = Math.min(toNumber(d0), toNumber(d1));
    const stop = Math.max(toNumber(d0), toNumber(d1));
    const isReversed = d0 > d1;
    const { interval } = this;
    let i;
    if (interval instanceof TimeInterval) {
      i = interval;
    } else {
      const tickCount = typeof interval === "number" ? (stop - start) / Math.max(interval, 1) : this.tickCount;
      i = this.getTickInterval({
        start,
        stop,
        count: tickCount,
        minCount: this.minTickCount,
        maxCount: this.maxTickCount
      });
    }
    if (i) {
      const intervalRange = i.range(new Date(start), new Date(stop), true);
      const domain = isReversed ? [...intervalRange].reverse() : intervalRange;
      const n0 = domain[0];
      const n1 = domain[domain.length - 1];
      this.niceDomain = [n0, n1];
    }
  }
};
var sparklines_util_exports = {};
__export(sparklines_util_exports, {
  Color: () => Color,
  DELETE: () => DELETE,
  Logger: () => Logger,
  Padding: () => Padding,
  angleBetween: () => angleBetween,
  checkDatum: () => checkDatum,
  clamp: () => clamp2,
  clampArray: () => clampArray,
  countFractionDigits: () => countFractionDigits,
  createId: () => createId,
  extent: () => extent,
  isContinuous: () => isContinuous,
  isDate: () => isDate2,
  isDiscrete: () => isDiscrete,
  isEqual: () => isEqual,
  isNegative: () => isNegative,
  isNumber: () => isNumber2,
  isNumberEqual: () => isEqual,
  isReal: () => isReal,
  isString: () => isString2,
  isStringObject: () => isStringObject,
  jsonApply: () => jsonApply,
  jsonClone: () => jsonClone,
  jsonDiff: () => jsonDiff,
  jsonMerge: () => jsonMerge,
  jsonWalk: () => jsonWalk,
  mod: () => mod,
  normalisedExtent: () => normalisedExtent,
  normalisedExtentWithMetadata: () => normalisedExtentWithMetadata,
  normalizeAngle180: () => normalizeAngle180,
  normalizeAngle360: () => normalizeAngle360,
  normalizeAngle360Inclusive: () => normalizeAngle360Inclusive,
  range: () => range,
  resetIds: () => resetIds,
  round: () => round,
  sanitizeHtml: () => sanitizeHtml,
  tickFormat: () => tickFormat,
  tickStep: () => tickStep,
  ticks: () => ticks_default,
  toDegrees: () => toDegrees,
  toFixed: () => toFixed,
  toRadians: () => toRadians,
  toReal: () => toReal,
  zipObject: () => zipObject
});
var Padding = class {
  constructor(top = 0, right = top, bottom = top, left = right) {
    this.top = top;
    this.right = right;
    this.bottom = bottom;
    this.left = left;
  }
  clear() {
    this.top = this.right = this.bottom = this.left = 0;
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER)
], Padding.prototype, "top", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], Padding.prototype, "right", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], Padding.prototype, "bottom", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], Padding.prototype, "left", 2);
var element = null;
function sanitizeHtml(text) {
  if (text == null) {
    return void 0;
  } else if (text === "") {
    return "";
  }
  element != null ? element : element = document.createElement("div");
  element.textContent = String(text);
  return element.innerHTML;
}
function areArrayNumbersEqual(arrA, arrB) {
  return arrA.length === arrB.length && arrA.every((item, i) => Number(item) === Number(arrB[i]));
}
function circleRectOverlap(c, x, y, w, h) {
  let edgeX = c.x;
  if (c.x < x) {
    edgeX = x;
  } else if (c.x > x + w) {
    edgeX = x + w;
  }
  let edgeY = c.y;
  if (c.y < y) {
    edgeY = y;
  } else if (c.y > y + h) {
    edgeY = y + h;
  }
  const dx = c.x - edgeX;
  const dy = c.y - edgeY;
  const d = Math.sqrt(dx * dx + dy * dy);
  return d <= c.size * 0.5;
}
function rectRectOverlap(r1, x2, y2, w2, h2) {
  const xOverlap = r1.x + r1.width > x2 && r1.x < x2 + w2;
  const yOverlap = r1.y + r1.height > y2 && r1.y < y2 + h2;
  return xOverlap && yOverlap;
}
function rectContainsRect(r1, r2x, r2y, r2w, r2h) {
  return r2x + r2w < r1.x + r1.width && r2x > r1.x && r2y > r1.y && r2y + r2h < r1.y + r1.height;
}
function isPointLabelDatum(x) {
  return x != null && typeof x.point === "object" && typeof x.label === "object";
}
function placeLabels(data, bounds, padding = 5) {
  const result = [];
  data = data.map((d) => d.slice().sort((a, b) => b.point.size - a.point.size));
  for (let j = 0; j < data.length; j++) {
    const labels = result[j] = [];
    const datum = data[j];
    if (!((datum == null ? void 0 : datum.length) && datum[0].label)) {
      continue;
    }
    for (let i = 0, ln = datum.length; i < ln; i++) {
      const d = datum[i];
      const l = d.label;
      const r = d.point.size * 0.5;
      const x = d.point.x - l.width * 0.5;
      const y = d.point.y - r - l.height - padding;
      const { width, height } = l;
      const withinBounds = !bounds || rectContainsRect(bounds, x, y, width, height);
      if (!withinBounds) {
        continue;
      }
      const overlapPoints = data.some(
        (datum2) => datum2.some((d2) => circleRectOverlap(d2.point, x, y, width, height))
      );
      if (overlapPoints) {
        continue;
      }
      const overlapLabels = result.some((labels2) => labels2.some((l2) => rectRectOverlap(l2, x, y, width, height)));
      if (overlapLabels) {
        continue;
      }
      labels.push({
        index: i,
        text: l.text,
        x,
        y,
        width,
        height,
        datum: d
      });
    }
  }
  return result;
}
function axisLabelsOverlap(data, padding) {
  const result = [];
  for (let i = 0; i < data.length; i++) {
    const datum = data[i];
    const {
      point: { x, y },
      label: { text }
    } = datum;
    let {
      label: { width, height }
    } = datum;
    width += padding != null ? padding : 0;
    height += padding != null ? padding : 0;
    const overlapLabels = result.some((l) => {
      return rectRectOverlap(l, x, y, width, height);
    });
    if (overlapLabels) {
      return true;
    }
    result.push({
      index: i,
      text,
      x,
      y,
      width,
      height,
      datum
    });
  }
  return false;
}
var GRID_STYLE_KEYS = ["stroke", "lineDash"];
var GRID_STYLE = ARRAY_OF(
  (value) => isObject(value) && Object.keys(value).every((key) => GRID_STYLE_KEYS.includes(key)),
  "objects with gridline style properties such as 'stroke' or 'lineDash'"
);
var AxisGridLine = class {
  constructor() {
    this.enabled = true;
    this.width = 1;
    this.style = [
      {
        stroke: void 0,
        lineDash: []
      }
    ];
  }
};
__decorateClass([
  Validate(BOOLEAN)
], AxisGridLine.prototype, "enabled", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], AxisGridLine.prototype, "width", 2);
__decorateClass([
  Validate(GRID_STYLE)
], AxisGridLine.prototype, "style", 2);
function Default(defaultValue, replaces = [void 0]) {
  return addTransformToInstanceProperty((_, __, v) => {
    if (replaces.includes(v)) {
      return defaultValue;
    }
    return v;
  });
}
var AxisLabel = class {
  constructor() {
    this.enabled = true;
    this.autoWrap = false;
    this.maxWidth = void 0;
    this.maxHeight = void 0;
    this.fontStyle = void 0;
    this.fontWeight = void 0;
    this.fontSize = 12;
    this.fontFamily = "Verdana, sans-serif";
    this.padding = 5;
    this.minSpacing = NaN;
    this.color = "rgba(87, 87, 87, 1)";
    this.rotation = void 0;
    this.avoidCollisions = true;
    this.mirrored = false;
    this.parallel = false;
    this.formatter = void 0;
  }
  /**
   * The side of the axis line to position the labels on.
   * -1 = left (default)
   * 1 = right
   */
  getSideFlag() {
    return this.mirrored ? 1 : -1;
  }
  getFont() {
    return getFont(this);
  }
};
__decorateClass([
  Validate(BOOLEAN)
], AxisLabel.prototype, "enabled", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], AxisLabel.prototype, "autoWrap", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], AxisLabel.prototype, "maxWidth", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], AxisLabel.prototype, "maxHeight", 2);
__decorateClass([
  Validate(FONT_STYLE, { optional: true })
], AxisLabel.prototype, "fontStyle", 2);
__decorateClass([
  Validate(FONT_WEIGHT, { optional: true })
], AxisLabel.prototype, "fontWeight", 2);
__decorateClass([
  Validate(NUMBER.restrict({ min: 1 }))
], AxisLabel.prototype, "fontSize", 2);
__decorateClass([
  Validate(STRING)
], AxisLabel.prototype, "fontFamily", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], AxisLabel.prototype, "padding", 2);
__decorateClass([
  Validate(NUMBER_OR_NAN),
  Default(NaN)
], AxisLabel.prototype, "minSpacing", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], AxisLabel.prototype, "color", 2);
__decorateClass([
  Validate(DEGREE, { optional: true })
], AxisLabel.prototype, "rotation", 2);
__decorateClass([
  Validate(BOOLEAN)
], AxisLabel.prototype, "avoidCollisions", 2);
__decorateClass([
  Validate(BOOLEAN)
], AxisLabel.prototype, "mirrored", 2);
__decorateClass([
  Validate(BOOLEAN)
], AxisLabel.prototype, "parallel", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], AxisLabel.prototype, "format", 2);
var AxisLine = class {
  constructor() {
    this.enabled = true;
    this.width = 1;
    this.color = void 0;
  }
};
__decorateClass([
  Validate(BOOLEAN)
], AxisLine.prototype, "enabled", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], AxisLine.prototype, "width", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], AxisLine.prototype, "color", 2);
var TICK_INTERVAL = predicateWithMessage(
  (value) => isFiniteNumber(value) && value > 0 || value instanceof TimeInterval,
  `a non-zero positive Number value or, for a time axis, a Time Interval such as 'agCharts.time.month'`
);
var AxisTick = class {
  constructor() {
    this.enabled = true;
    this.width = 1;
    this.size = 6;
    this.color = void 0;
    this.interval = void 0;
    this.values = void 0;
    this.minSpacing = NaN;
  }
};
__decorateClass([
  Validate(BOOLEAN)
], AxisTick.prototype, "enabled", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], AxisTick.prototype, "width", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], AxisTick.prototype, "size", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], AxisTick.prototype, "color", 2);
__decorateClass([
  Validate(TICK_INTERVAL, { optional: true })
], AxisTick.prototype, "interval", 2);
__decorateClass([
  Validate(ARRAY, { optional: true })
], AxisTick.prototype, "values", 2);
__decorateClass([
  Validate(MIN_SPACING),
  Default(NaN)
], AxisTick.prototype, "minSpacing", 2);
function prepareAxisAnimationContext(axis) {
  const requestedRangeMin = Math.min(...axis.range);
  const requestedRangeMax = Math.max(...axis.range);
  const min = Math.floor(requestedRangeMin);
  const max = Math.ceil(requestedRangeMax);
  const visible = min !== max;
  return { min, max, visible };
}
var fullCircle = Math.PI * 2;
var halfCircle = fullCircle / 2;
function normaliseEndRotation(start, end) {
  const directDistance = Math.abs(end - start);
  if (directDistance < halfCircle)
    return end;
  if (start > end)
    return end + fullCircle;
  return end - fullCircle;
}
function prepareAxisAnimationFunctions(ctx) {
  const outOfBounds = (y, range3) => {
    const min = range3 != null ? Math.min(...range3) : ctx.min;
    const max = range3 != null ? Math.max(...range3) : ctx.max;
    return y < min || y > max;
  };
  const calculateStatus2 = (node, datum, status) => {
    if (status !== "removed" && outOfBounds(node.translationY, node.datum.range)) {
      return "removed";
    } else if (status !== "added" && outOfBounds(datum.translationY, datum.range)) {
      return "added";
    }
    return status;
  };
  const tick = {
    fromFn(node, datum, status) {
      let y = node.y1 + node.translationY;
      let opacity = node.opacity;
      if (status === "added" || outOfBounds(node.datum.translationY, node.datum.range)) {
        y = datum.translationY;
        opacity = 0;
      }
      return __spreadValues({ y: 0, translationY: y, opacity }, FROM_TO_MIXINS[status]);
    },
    toFn(_node, datum, status) {
      const y = datum.translationY;
      let opacity = 1;
      if (status === "removed") {
        opacity = 0;
      }
      return {
        y: 0,
        translationY: y,
        opacity,
        finish: {
          // Set explicit y after animation so it's pixel aligned
          y,
          translationY: 0
        }
      };
    },
    intermediateFn(node, _datum, _status) {
      return { visible: !outOfBounds(node.y) };
    }
  };
  const label = {
    fromFn(node, newDatum, status) {
      var _a;
      const datum = (_a = node.previousDatum) != null ? _a : newDatum;
      status = calculateStatus2(node, newDatum, status);
      const x = datum.x;
      const y = datum.y;
      const rotationCenterX = datum.rotationCenterX;
      let translationY = Math.round(node.translationY);
      let rotation = datum.rotation;
      let opacity = node.opacity;
      if (status === "removed" || outOfBounds(datum.y, datum.range)) {
      } else if (status === "added" || outOfBounds(node.datum.y, node.datum.range)) {
        translationY = Math.round(datum.translationY);
        opacity = 0;
        rotation = newDatum.rotation;
      }
      return __spreadValues({ x, y, rotationCenterX, translationY, rotation, opacity }, FROM_TO_MIXINS[status]);
    },
    toFn(node, datum, status) {
      var _a, _b;
      const x = datum.x;
      const y = datum.y;
      const rotationCenterX = datum.rotationCenterX;
      const translationY = Math.round(datum.translationY);
      let rotation = 0;
      let opacity = 1;
      status = calculateStatus2(node, datum, status);
      if (status === "added") {
        opacity = 1;
        rotation = datum.rotation;
      } else if (status === "removed") {
        opacity = 0;
        rotation = datum.rotation;
      } else {
        rotation = normaliseEndRotation((_b = (_a = node.previousDatum) == null ? void 0 : _a.rotation) != null ? _b : datum.rotation, datum.rotation);
      }
      return { x, y, rotationCenterX, translationY, rotation, opacity, finish: { rotation: datum.rotation } };
    }
  };
  const line = {
    fromFn(node, datum) {
      var _a;
      return __spreadValues(__spreadValues({}, (_a = node.previousDatum) != null ? _a : datum), FROM_TO_MIXINS["updated"]);
    },
    toFn(_node, datum) {
      return __spreadValues({}, datum);
    }
  };
  const group2 = {
    fromFn(group3, _datum) {
      const { rotation, translationX, translationY } = group3;
      return __spreadValues({
        rotation,
        translationX,
        translationY
      }, FROM_TO_MIXINS["updated"]);
    },
    toFn(_group, datum) {
      const { rotation, translationX, translationY } = datum;
      return {
        rotation,
        translationX,
        translationY
      };
    }
  };
  return { tick, line, label, group: group2 };
}
function resetAxisGroupFn() {
  return (_node, datum) => {
    return {
      rotation: datum.rotation,
      rotationCenterX: datum.rotationCenterX,
      rotationCenterY: datum.rotationCenterY,
      translationX: datum.translationX,
      translationY: datum.translationY
    };
  };
}
function resetAxisSelectionFn(ctx) {
  const { visible: rangeVisible, min, max } = ctx;
  return (_node, datum) => {
    const y = datum.translationY;
    const visible = rangeVisible && y >= min && y <= max;
    return {
      y,
      translationY: 0,
      opacity: 1,
      visible
    };
  };
}
function resetAxisLabelSelectionFn() {
  return (_node, datum) => {
    return {
      x: datum.x,
      y: datum.y,
      translationY: datum.translationY,
      rotation: datum.rotation,
      rotationCenterX: datum.rotationCenterX
    };
  };
}
function resetAxisLineSelectionFn() {
  return (_node, datum) => {
    return __spreadValues({}, datum);
  };
}
var Tags = /* @__PURE__ */ ((Tags2) => {
  Tags2[Tags2["TickLine"] = 0] = "TickLine";
  Tags2[Tags2["TickLabel"] = 1] = "TickLabel";
  Tags2[Tags2["GridLine"] = 2] = "GridLine";
  Tags2[Tags2["GridArc"] = 3] = "GridArc";
  Tags2[Tags2["AxisLine"] = 4] = "AxisLine";
  return Tags2;
})(Tags || {});
var _Axis = class _Axis2 {
  constructor(moduleCtx, scale2) {
    this.moduleCtx = moduleCtx;
    this.scale = scale2;
    this.id = createId(this);
    this.nice = true;
    this.reverse = void 0;
    this.dataDomain = { domain: [], clipped: false };
    this.keys = [];
    this.boundSeries = [];
    this.includeInvisibleDomains = false;
    this.axisGroup = new Group({
      name: `${this.id}-axis`,
      zIndex: 2
      /* AXIS_ZINDEX */
    });
    this.lineNode = this.axisGroup.appendChild(new Line());
    this.tickLineGroup = this.axisGroup.appendChild(
      new Group({
        name: `${this.id}-Axis-tick-lines`,
        zIndex: 2
        /* AXIS_ZINDEX */
      })
    );
    this.tickLabelGroup = this.axisGroup.appendChild(
      new Group({
        name: `${this.id}-Axis-tick-labels`,
        zIndex: 2
        /* AXIS_ZINDEX */
      })
    );
    this.crossLineGroup = new Group({ name: `${this.id}-CrossLines` });
    this.gridGroup = new Group({ name: `${this.id}-Axis-grid` });
    this.gridLineGroup = this.gridGroup.appendChild(
      new Group({
        name: `${this.id}-gridLines`,
        zIndex: 1
        /* AXIS_GRID_ZINDEX */
      })
    );
    this.tickLineGroupSelection = Selection.select(this.tickLineGroup, Line, false);
    this.tickLabelGroupSelection = Selection.select(this.tickLabelGroup, Text, false);
    this.gridLineGroupSelection = Selection.select(this.gridLineGroup, Line, false);
    this.line = new AxisLine();
    this.tick = this.createTick();
    this.gridLine = new AxisGridLine();
    this.label = this.createLabel();
    this.defaultTickMinSpacing = _Axis2.defaultTickMinSpacing;
    this.translation = { x: 0, y: 0 };
    this.rotation = 0;
    this.layout = {
      label: {
        fractionDigits: 0,
        padding: this.label.padding,
        format: this.label.format
      }
    };
    this.destroyFns = [];
    this.range = [0, 1];
    this.visibleRange = [0, 1];
    this.title = void 0;
    this._titleCaption = new Caption();
    this._gridLength = 0;
    this.fractionDigits = 0;
    this.gridPadding = 0;
    this.seriesAreaPadding = 0;
    this.tickGenerationResult = void 0;
    this.maxThickness = Infinity;
    this.moduleMap = new ModuleMap();
    this.refreshScale();
    this._titleCaption.registerInteraction(this.moduleCtx);
    this._titleCaption.node.rotation = -Math.PI / 2;
    this.axisGroup.appendChild(this._titleCaption.node);
    this.destroyFns.push(moduleCtx.interactionManager.addListener("hover", (e) => this.checkAxisHover(e)));
    this.animationManager = moduleCtx.animationManager;
    this.animationState = new StateMachine("empty", {
      empty: {
        update: {
          target: "ready",
          action: () => this.resetSelectionNodes()
        }
      },
      ready: {
        update: (data) => this.animateReadyUpdate(data),
        resize: () => this.resetSelectionNodes()
      }
    });
    this._crossLines = [];
    this.assignCrossLineArrayConstructor(this._crossLines);
    let previousSize = void 0;
    this.destroyFns.push(
      moduleCtx.layoutService.addListener("layout-complete", (e) => {
        if (previousSize != null && jsonDiff(e.chart, previousSize) != null) {
          this.animationState.transition("resize");
        }
        previousSize = __spreadValues({}, e.chart);
      })
    );
    this.destroyFns.push(
      moduleCtx.updateService.addListener("update-complete", (e) => {
        this.minRect = e.minRect;
      })
    );
  }
  get type() {
    var _a;
    return (_a = this.constructor.type) != null ? _a : "";
  }
  set crossLines(value) {
    var _a, _b;
    (_a = this._crossLines) == null ? void 0 : _a.forEach((crossLine) => this.detachCrossLine(crossLine));
    if (value) {
      this.assignCrossLineArrayConstructor(value);
    }
    this._crossLines = value;
    (_b = this._crossLines) == null ? void 0 : _b.forEach((crossLine) => {
      this.attachCrossLine(crossLine);
      this.initCrossLine(crossLine);
    });
  }
  get crossLines() {
    return this._crossLines;
  }
  attachCrossLine(crossLine) {
    this.crossLineGroup.appendChild(crossLine.group);
    this.crossLineGroup.appendChild(crossLine.labelGroup);
  }
  detachCrossLine(crossLine) {
    this.crossLineGroup.removeChild(crossLine.group);
    this.crossLineGroup.removeChild(crossLine.labelGroup);
  }
  destroy() {
    this.moduleMap.destroy();
    this.destroyFns.forEach((f) => f());
  }
  refreshScale() {
    var _a;
    this.range = this.scale.range.slice();
    (_a = this.crossLines) == null ? void 0 : _a.forEach((crossLine) => {
      this.initCrossLine(crossLine);
    });
  }
  updateRange() {
    var _a;
    const { range: rr, visibleRange: vr, scale: scale2 } = this;
    const span = (rr[1] - rr[0]) / (vr[1] - vr[0]);
    const shift = span * vr[0];
    const start = rr[0] - shift;
    scale2.range = [start, start + span];
    (_a = this.crossLines) == null ? void 0 : _a.forEach((crossLine) => {
      crossLine.clippedRange = [rr[0], rr[1]];
    });
  }
  setCrossLinesVisible(visible) {
    this.crossLineGroup.visible = visible;
  }
  attachAxis(axisNode, gridNode) {
    gridNode.appendChild(this.gridGroup);
    axisNode.appendChild(this.axisGroup);
    axisNode.appendChild(this.crossLineGroup);
  }
  detachAxis(axisNode, gridNode) {
    gridNode.removeChild(this.gridGroup);
    axisNode.removeChild(this.axisGroup);
    axisNode.removeChild(this.crossLineGroup);
  }
  /**
   * Checks if a point or an object is in range.
   * @param x A point (or object's starting point).
   * @param width Object's width.
   * @param tolerance Expands the range on both ends by this amount.
   */
  inRange(x, width = 0, tolerance = 0) {
    const min = Math.min(...this.range);
    const max = Math.max(...this.range);
    return x + width >= min - tolerance && x <= max + tolerance;
  }
  onLabelFormatChange(ticks, format2) {
    const { scale: scale2, fractionDigits } = this;
    const logScale = scale2 instanceof LogScale;
    const defaultLabelFormatter = !logScale && fractionDigits > 0 ? (x) => typeof x === "number" ? x.toFixed(fractionDigits) : String(x) : (x) => String(x);
    if (format2 && scale2 && scale2.tickFormat) {
      try {
        this.labelFormatter = scale2.tickFormat({ ticks, specifier: format2 });
      } catch (e) {
        this.labelFormatter = defaultLabelFormatter;
        Logger.warnOnce(`the axis label format string ${format2} is invalid. No formatting will be applied`);
      }
    } else {
      this.labelFormatter = defaultLabelFormatter;
    }
  }
  setDomain() {
    const {
      scale: scale2,
      dataDomain: { domain }
    } = this;
    scale2.domain = domain;
  }
  setTickInterval(interval) {
    var _a;
    this.scale.interval = (_a = this.tick.interval) != null ? _a : interval;
  }
  setTickCount(count2, minTickCount, maxTickCount) {
    const { scale: scale2 } = this;
    if (!(count2 && ContinuousScale.is(scale2))) {
      return;
    }
    if (typeof count2 === "number") {
      scale2.tickCount = count2;
      scale2.minTickCount = minTickCount != null ? minTickCount : 0;
      scale2.maxTickCount = maxTickCount != null ? maxTickCount : Infinity;
      return;
    }
    if (scale2 instanceof TimeScale) {
      this.setTickInterval(count2);
    }
  }
  set gridLength(value) {
    var _a;
    if (this._gridLength && !value || !this._gridLength && value) {
      this.gridLineGroupSelection.clear();
    }
    this._gridLength = value;
    (_a = this.crossLines) == null ? void 0 : _a.forEach((crossLine) => {
      this.initCrossLine(crossLine);
    });
  }
  get gridLength() {
    return this._gridLength;
  }
  createTick() {
    return new AxisTick();
  }
  createLabel() {
    return new AxisLabel();
  }
  checkAxisHover(event) {
    const bbox = this.computeBBox();
    const isInAxis = bbox.containsPoint(event.offsetX, event.offsetY);
    if (!isInAxis)
      return;
    this.moduleCtx.chartEventManager.axisHover(this.id, this.direction);
  }
  /**
   * Creates/removes/updates the scene graph nodes that constitute the axis.
   */
  update(primaryTickCount) {
    if (!this.tickGenerationResult) {
      return;
    }
    const { rotation, parallelFlipRotation, regularFlipRotation } = this.calculateRotations();
    const sideFlag = this.label.getSideFlag();
    this.updatePosition();
    const lineData = this.getAxisLineCoordinates();
    const _a = this.tickGenerationResult, { tickData, combinedRotation, textBaseline, textAlign } = _a, ticksResult = __objRest(_a, ["tickData", "combinedRotation", "textBaseline", "textAlign"]);
    const previousTicks = this.tickLabelGroupSelection.nodes().map((node) => node.datum.tickId);
    this.updateSelections(lineData, tickData.ticks, {
      combinedRotation,
      textAlign,
      textBaseline,
      range: this.scale.range
    });
    if (this.animationManager.isSkipped()) {
      this.resetSelectionNodes();
    } else {
      const diff2 = this.calculateUpdateDiff(previousTicks, tickData);
      this.animationState.transition("update", diff2);
    }
    this.updateAxisLine();
    this.updateLabels();
    this.updateVisibility();
    this.updateGridLines(sideFlag);
    this.updateTickLines();
    this.updateTitle({ anyTickVisible: tickData.ticks.length > 0 });
    this.updateCrossLines({ rotation, parallelFlipRotation, regularFlipRotation });
    this.updateLayoutState();
    primaryTickCount = ticksResult.primaryTickCount;
    return primaryTickCount;
  }
  getAxisLineCoordinates() {
    const {
      range: [start, end]
    } = this;
    const x = 0;
    const y1 = Math.min(start, end);
    const y2 = Math.max(start, end);
    return { x, y1, y2 };
  }
  getTickLineCoordinates(datum) {
    const { label } = this;
    const sideFlag = label.getSideFlag();
    const x = sideFlag * this.getTickSize();
    const x1 = Math.min(0, x);
    const x2 = x1 + Math.abs(x);
    const y = datum.translationY;
    return { x1, x2, y };
  }
  getTickLabelProps(datum, params) {
    const { label } = this;
    const { combinedRotation, textBaseline, textAlign, range: range3 } = params;
    const text = datum.tickLabel;
    const sideFlag = label.getSideFlag();
    const labelX = sideFlag * (this.getTickSize() + label.padding + this.seriesAreaPadding);
    const visible = text !== "" && text != void 0;
    return {
      tickId: datum.tickId,
      translationY: datum.translationY,
      fill: label.color,
      fontFamily: label.fontFamily,
      fontSize: label.fontSize,
      fontStyle: label.fontStyle,
      fontWeight: label.fontWeight,
      rotation: combinedRotation,
      rotationCenterX: labelX,
      text,
      textAlign,
      textBaseline,
      visible,
      x: labelX,
      y: 0,
      range: range3
    };
  }
  getTickSize() {
    return this.tick.enabled ? this.tick.size : this.createTick().size;
  }
  setTitleProps(caption, params) {
    var _a;
    const { title } = this;
    if (!title) {
      caption.enabled = false;
      return;
    }
    caption.color = title.color;
    caption.fontFamily = title.fontFamily;
    caption.fontSize = title.fontSize;
    caption.fontStyle = title.fontStyle;
    caption.fontWeight = title.fontWeight;
    caption.enabled = title.enabled;
    caption.wrapping = title.wrapping;
    if (title.enabled) {
      const titleNode = caption.node;
      const padding = ((_a = title.spacing) != null ? _a : 0) + params.spacing;
      const sideFlag = this.label.getSideFlag();
      const parallelFlipRotation = normalizeAngle360(this.rotation);
      const titleRotationFlag = sideFlag === -1 && parallelFlipRotation > Math.PI && parallelFlipRotation < Math.PI * 2 ? -1 : 1;
      const rotation = titleRotationFlag * sideFlag * Math.PI / 2;
      const textBaseline = titleRotationFlag === 1 ? "bottom" : "top";
      const { range: range3 } = this;
      const x = Math.floor(titleRotationFlag * sideFlag * (range3[0] + range3[1]) / 2);
      const y = sideFlag === -1 ? Math.floor(titleRotationFlag * -padding) : Math.floor(-padding);
      const { callbackCache } = this.moduleCtx;
      const { formatter = (params2) => params2.defaultValue } = title;
      const text = callbackCache.call(formatter, this.getTitleFormatterParams());
      titleNode.setProperties({
        rotation,
        text,
        textBaseline,
        visible: true,
        x,
        y
      });
    }
  }
  calculateLayout(primaryTickCount) {
    var _b;
    const { rotation, parallelFlipRotation, regularFlipRotation } = this.calculateRotations();
    const sideFlag = this.label.getSideFlag();
    const labelX = sideFlag * (this.getTickSize() + this.label.padding + this.seriesAreaPadding);
    this.updateScale();
    this.tickGenerationResult = this.generateTicks({
      primaryTickCount,
      parallelFlipRotation,
      regularFlipRotation,
      labelX,
      sideFlag
    });
    this.updateLayoutState();
    const _a = this.tickGenerationResult, { tickData, combinedRotation, textBaseline, textAlign } = _a, ticksResult = __objRest(_a, ["tickData", "combinedRotation", "textBaseline", "textAlign"]);
    const boxes = [];
    const { x, y1, y2 } = this.getAxisLineCoordinates();
    const lineBox = new BBox(
      x + Math.min(sideFlag * this.seriesAreaPadding, 0),
      y1,
      this.seriesAreaPadding,
      y2 - y1
    );
    boxes.push(lineBox);
    const { tick } = this;
    if (tick.enabled) {
      tickData.ticks.forEach((datum) => {
        const { x1, x2, y } = this.getTickLineCoordinates(datum);
        const tickLineBox = new BBox(x1, y, x2 - x1, 0);
        boxes.push(tickLineBox);
      });
    }
    const { label } = this;
    if (label.enabled) {
      const tempText = new Text();
      tickData.ticks.forEach((datum) => {
        const labelProps = this.getTickLabelProps(datum, {
          combinedRotation,
          textAlign,
          textBaseline,
          range: this.scale.range
        });
        if (!labelProps.visible) {
          return;
        }
        tempText.setProperties(__spreadProps(__spreadValues({}, labelProps), {
          translationY: Math.round(datum.translationY)
        }));
        const box = tempText.computeTransformedBBox();
        if (box) {
          boxes.push(box);
        }
      });
    }
    const getTransformBox = (bbox2) => {
      const matrix = new Matrix();
      const {
        rotation: axisRotation,
        translationX,
        translationY,
        rotationCenterX,
        rotationCenterY
      } = this.getAxisTransform();
      Matrix.updateTransformMatrix(matrix, 1, 1, axisRotation, translationX, translationY, {
        scalingCenterX: 0,
        scalingCenterY: 0,
        rotationCenterX,
        rotationCenterY
      });
      return matrix.transformBBox(bbox2);
    };
    const { title } = this;
    if (title == null ? void 0 : title.enabled) {
      const caption = new Caption();
      const spacing = BBox.merge(boxes).width;
      this.setTitleProps(caption, { spacing });
      const titleNode = caption.node;
      const titleBox = titleNode.computeTransformedBBox();
      if (titleBox) {
        boxes.push(titleBox);
      }
    }
    const bbox = BBox.merge(boxes);
    const transformedBBox = getTransformBox(bbox);
    const anySeriesActive = this.isAnySeriesActive();
    (_b = this.crossLines) == null ? void 0 : _b.forEach((crossLine) => {
      var _a2;
      crossLine.sideFlag = -sideFlag;
      crossLine.direction = rotation === -Math.PI / 2 ? "x" : "y";
      if (crossLine instanceof CartesianCrossLine) {
        crossLine.label.parallel = (_a2 = crossLine.label.parallel) != null ? _a2 : this.label.parallel;
      }
      crossLine.parallelFlipRotation = parallelFlipRotation;
      crossLine.regularFlipRotation = regularFlipRotation;
      crossLine.calculateLayout(anySeriesActive, this.reverse);
    });
    primaryTickCount = ticksResult.primaryTickCount;
    return { primaryTickCount, bbox: transformedBBox };
  }
  updateLayoutState() {
    this.layout.label = {
      fractionDigits: this.fractionDigits,
      padding: this.label.padding,
      format: this.label.format
    };
  }
  updateScale() {
    this.updateRange();
    this.calculateDomain();
    this.setDomain();
    this.setTickInterval(this.tick.interval);
    const { scale: scale2, nice } = this;
    if (!ContinuousScale.is(scale2)) {
      return;
    }
    scale2.nice = nice;
    scale2.update();
  }
  calculateRotations() {
    const rotation = toRadians(this.rotation);
    const parallelFlipRotation = normalizeAngle360(rotation);
    const regularFlipRotation = normalizeAngle360(rotation - Math.PI / 2);
    return { rotation, parallelFlipRotation, regularFlipRotation };
  }
  generateTicks({
    primaryTickCount,
    parallelFlipRotation,
    regularFlipRotation,
    labelX,
    sideFlag
  }) {
    var _a;
    const {
      scale: scale2,
      tick,
      label: { parallel, rotation, fontFamily, fontSize, fontStyle, fontWeight }
    } = this;
    const secondaryAxis = primaryTickCount !== void 0;
    const { defaultRotation, configuredRotation, parallelFlipFlag, regularFlipFlag } = calculateLabelRotation({
      rotation,
      parallel,
      regularFlipRotation,
      parallelFlipRotation
    });
    const initialRotation = configuredRotation + defaultRotation;
    const labelMatrix = new Matrix();
    const { maxTickCount } = this.estimateTickCount({
      minSpacing: tick.minSpacing,
      maxSpacing: (_a = tick.maxSpacing) != null ? _a : NaN
    });
    const continuous = ContinuousScale.is(scale2);
    const maxIterations = !continuous || isNaN(maxTickCount) ? 10 : maxTickCount;
    let textAlign = getTextAlign(parallel, configuredRotation, 0, sideFlag, regularFlipFlag);
    const textBaseline = getTextBaseline(parallel, configuredRotation, sideFlag, parallelFlipFlag);
    const textProps = {
      fontFamily,
      fontSize,
      fontStyle,
      fontWeight,
      textBaseline,
      textAlign
    };
    let tickData = {
      rawTicks: [],
      ticks: [],
      labelCount: 0
    };
    let index = 0;
    let autoRotation = 0;
    let labelOverlap = true;
    let terminate = false;
    while (labelOverlap && index <= maxIterations) {
      if (terminate) {
        break;
      }
      autoRotation = 0;
      textAlign = getTextAlign(parallel, configuredRotation, 0, sideFlag, regularFlipFlag);
      const tickStrategies = this.getTickStrategies({ secondaryAxis, index });
      for (const strategy of tickStrategies) {
        ({ tickData, index, autoRotation, terminate } = strategy({
          index,
          tickData,
          textProps,
          labelOverlap,
          terminate,
          primaryTickCount
        }));
        const rotated = configuredRotation !== 0 || autoRotation !== 0;
        const rotation2 = initialRotation + autoRotation;
        textAlign = getTextAlign(parallel, configuredRotation, autoRotation, sideFlag, regularFlipFlag);
        labelOverlap = this.checkLabelOverlap(rotation2, rotated, labelMatrix, tickData.ticks, labelX, __spreadProps(__spreadValues({}, textProps), {
          textAlign
        }));
      }
    }
    const combinedRotation = defaultRotation + configuredRotation + autoRotation;
    if (!secondaryAxis && tickData.rawTicks.length > 0) {
      primaryTickCount = tickData.rawTicks.length;
    }
    return { tickData, primaryTickCount, combinedRotation, textBaseline, textAlign };
  }
  getTickStrategies({ index, secondaryAxis }) {
    const { scale: scale2, label, tick } = this;
    const continuous = ContinuousScale.is(scale2);
    const avoidLabelCollisions = label.enabled && label.avoidCollisions;
    const filterTicks = !continuous && index !== 0 && avoidLabelCollisions;
    const autoRotate = label.autoRotate === true && label.rotation === void 0;
    const strategies = [];
    let tickGenerationType;
    if (this.tick.values) {
      tickGenerationType = 3;
    } else if (secondaryAxis) {
      tickGenerationType = 1;
    } else if (filterTicks) {
      tickGenerationType = 2;
    } else {
      tickGenerationType = 0;
    }
    const tickGenerationStrategy = ({ index: index2, tickData, primaryTickCount, terminate }) => this.createTickData(tickGenerationType, index2, tickData, terminate, primaryTickCount);
    strategies.push(tickGenerationStrategy);
    if (!continuous && !isNaN(tick.minSpacing)) {
      const tickFilterStrategy = ({ index: index2, tickData, primaryTickCount, terminate }) => this.createTickData(2, index2, tickData, terminate, primaryTickCount);
      strategies.push(tickFilterStrategy);
    }
    if (!avoidLabelCollisions) {
      return strategies;
    }
    if (label.autoWrap) {
      const autoWrapStrategy = ({ index: index2, tickData, textProps }) => this.wrapLabels(tickData, index2, textProps);
      strategies.push(autoWrapStrategy);
    } else if (autoRotate) {
      const autoRotateStrategy = ({ index: index2, tickData, labelOverlap, terminate }) => ({
        index: index2,
        tickData,
        autoRotation: this.getAutoRotation(labelOverlap),
        terminate
      });
      strategies.push(autoRotateStrategy);
    }
    return strategies;
  }
  createTickData(tickGenerationType, index, tickData, terminate, primaryTickCount) {
    var _a;
    const { scale: scale2, tick } = this;
    const { maxTickCount, minTickCount, defaultTickCount } = this.estimateTickCount({
      minSpacing: tick.minSpacing,
      maxSpacing: (_a = tick.maxSpacing) != null ? _a : NaN
    });
    const continuous = ContinuousScale.is(scale2);
    const maxIterations = !continuous || isNaN(maxTickCount) ? 10 : maxTickCount;
    let tickCount = continuous ? Math.max(defaultTickCount - index, minTickCount) : maxTickCount;
    const regenerateTicks = tick.interval === void 0 && tick.values === void 0 && tickCount > minTickCount && (continuous || tickGenerationType === 2);
    let unchanged = true;
    while (unchanged && index <= maxIterations) {
      const prevTicks = tickData.rawTicks;
      tickCount = continuous ? Math.max(defaultTickCount - index, minTickCount) : maxTickCount;
      const { rawTicks, ticks, labelCount } = this.getTicks({
        tickGenerationType,
        previousTicks: prevTicks,
        tickCount,
        minTickCount,
        maxTickCount,
        primaryTickCount
      });
      tickData.rawTicks = rawTicks;
      tickData.ticks = ticks;
      tickData.labelCount = labelCount;
      unchanged = regenerateTicks ? areArrayNumbersEqual(rawTicks, prevTicks) : false;
      index++;
    }
    const shouldTerminate = tick.interval !== void 0 || tick.values !== void 0;
    terminate || (terminate = shouldTerminate);
    return { tickData, index, autoRotation: 0, terminate };
  }
  checkLabelOverlap(rotation, rotated, labelMatrix, tickData, labelX, textProps) {
    Matrix.updateTransformMatrix(labelMatrix, 1, 1, rotation, 0, 0);
    const labelData = this.createLabelData(tickData, labelX, textProps, labelMatrix);
    const labelSpacing = getLabelSpacing(this.label.minSpacing, rotated);
    return axisLabelsOverlap(labelData, labelSpacing);
  }
  createLabelData(tickData, labelX, textProps, labelMatrix) {
    const labelData = [];
    for (const tickDatum of tickData) {
      const { tickLabel, translationY } = tickDatum;
      if (tickLabel === "" || tickLabel == void 0) {
        continue;
      }
      const lines = splitText(tickLabel);
      const { width, height } = measureText(lines, labelX, translationY, textProps);
      const bbox = new BBox(labelX, translationY, width, height);
      const labelDatum = calculateLabelBBox(tickLabel, bbox, labelX, translationY, labelMatrix);
      labelData.push(labelDatum);
    }
    return labelData;
  }
  getAutoRotation(labelOverlap) {
    var _a;
    return labelOverlap ? normalizeAngle360(toRadians((_a = this.label.autoRotateAngle) != null ? _a : 0)) : 0;
  }
  getTicks({
    tickGenerationType,
    previousTicks,
    tickCount,
    minTickCount,
    maxTickCount,
    primaryTickCount
  }) {
    var _a;
    const { range: range3, scale: scale2, visibleRange } = this;
    let rawTicks = [];
    switch (tickGenerationType) {
      case 3:
        if (ContinuousScale.is(scale2)) {
          const scaleDomain = scale2.getDomain();
          const start2 = scale2.fromDomain(scaleDomain[0]);
          const stop = scale2.fromDomain(scaleDomain[1]);
          const d0 = Math.min(start2, stop);
          const d1 = Math.max(start2, stop);
          rawTicks = this.tick.values.filter((value) => value >= d0 && value <= d1).sort((a, b) => a - b);
        } else {
          rawTicks = this.tick.values;
        }
        break;
      case 1:
        rawTicks = this.updateSecondaryAxisTicks(primaryTickCount);
        break;
      case 2:
        rawTicks = this.filterTicks(previousTicks, tickCount);
        break;
      default:
        rawTicks = this.createTicks(tickCount, minTickCount, maxTickCount);
        break;
    }
    this.fractionDigits = rawTicks.fractionDigits >= 0 ? rawTicks.fractionDigits : 0;
    this.onLabelFormatChange(rawTicks, this.label.format);
    const halfBandwidth = ((_a = scale2.bandwidth) != null ? _a : 0) / 2;
    const ticks = [];
    let labelCount = 0;
    const tickIdCounts = /* @__PURE__ */ new Map();
    const start = Math.max(0, Math.floor(visibleRange[0] * rawTicks.length));
    const end = Math.min(rawTicks.length, Math.ceil(visibleRange[1] * rawTicks.length));
    for (let i = start; i < end; i++) {
      const rawTick = rawTicks[i];
      const translationY = scale2.convert(rawTick) + halfBandwidth;
      if (range3.length > 0 && !this.inRange(translationY, 0, 1e-3))
        continue;
      const tickLabel = this.formatTick(rawTick, i);
      let tickId = tickLabel;
      if (tickIdCounts.has(tickId)) {
        const count2 = tickIdCounts.get(tickId);
        tickIdCounts.set(tickId, count2 + 1);
        tickId = `${tickId}_${count2}`;
      } else {
        tickIdCounts.set(tickId, 1);
      }
      ticks.push({ tick: rawTick, tickId, tickLabel, translationY });
      if (tickLabel === "" || tickLabel == void 0) {
        continue;
      }
      labelCount++;
    }
    return { rawTicks, ticks, labelCount };
  }
  filterTicks(ticks, tickCount) {
    var _a;
    const tickSpacing = !isNaN(this.tick.minSpacing) || !isNaN((_a = this.tick.maxSpacing) != null ? _a : NaN);
    const keepEvery = tickSpacing ? Math.ceil(ticks.length / tickCount) : 2;
    return ticks.filter((_, i) => i % keepEvery === 0);
  }
  createTicks(tickCount, minTickCount, maxTickCount) {
    var _a, _b, _c;
    this.setTickCount(tickCount, minTickCount, maxTickCount);
    return (_c = (_b = (_a = this.scale).ticks) == null ? void 0 : _b.call(_a)) != null ? _c : [];
  }
  estimateTickCount({ minSpacing, maxSpacing }) {
    const { minRect } = this;
    const rangeWithBleed = this.calculateRangeWithBleed();
    const defaultMinSpacing = Math.max(
      this.defaultTickMinSpacing,
      rangeWithBleed / ContinuousScale.defaultMaxTickCount
    );
    let clampMaxTickCount = !isNaN(maxSpacing);
    if (isNaN(minSpacing)) {
      minSpacing = defaultMinSpacing;
    }
    if (isNaN(maxSpacing)) {
      maxSpacing = rangeWithBleed;
    }
    if (minSpacing > maxSpacing) {
      if (minSpacing === defaultMinSpacing) {
        minSpacing = maxSpacing;
      } else {
        maxSpacing = minSpacing;
      }
    }
    const minRectDistance = minRect ? this.direction === "x" ? minRect.width : minRect.height : 1;
    clampMaxTickCount && (clampMaxTickCount = minRectDistance < defaultMinSpacing);
    const maxTickCount = clamp2(
      1,
      Math.floor(rangeWithBleed / minSpacing),
      clampMaxTickCount ? Math.floor(rangeWithBleed / minRectDistance) : Infinity
    );
    const minTickCount = Math.min(maxTickCount, Math.ceil(rangeWithBleed / maxSpacing));
    const defaultTickCount = clamp2(minTickCount, ContinuousScale.defaultTickCount, maxTickCount);
    return { minTickCount, maxTickCount, defaultTickCount };
  }
  updateVisibility() {
    if (this.moduleCtx.animationManager.isSkipped()) {
      this.resetSelectionNodes();
    }
    this.tickLineGroup.visible = this.tick.enabled;
    this.gridLineGroup.visible = this.gridLine.enabled;
    this.tickLabelGroup.visible = this.label.enabled;
  }
  updateCrossLines({
    rotation,
    parallelFlipRotation,
    regularFlipRotation
  }) {
    var _a;
    const sideFlag = this.label.getSideFlag();
    const anySeriesActive = this.isAnySeriesActive();
    (_a = this.crossLines) == null ? void 0 : _a.forEach((crossLine) => {
      var _a2;
      crossLine.sideFlag = -sideFlag;
      crossLine.direction = rotation === -Math.PI / 2 ? "x" : "y";
      if (crossLine instanceof CartesianCrossLine) {
        crossLine.label.parallel = (_a2 = crossLine.label.parallel) != null ? _a2 : this.label.parallel;
      }
      crossLine.parallelFlipRotation = parallelFlipRotation;
      crossLine.regularFlipRotation = regularFlipRotation;
      crossLine.update(anySeriesActive);
    });
  }
  updateTickLines() {
    const { tick, label } = this;
    const sideFlag = label.getSideFlag();
    this.tickLineGroupSelection.each((line) => {
      line.strokeWidth = tick.width;
      line.stroke = tick.color;
      line.x1 = sideFlag * this.getTickSize();
      line.x2 = 0;
    });
  }
  calculateAvailableRange() {
    const { range: range3 } = this;
    const min = Math.min(...range3);
    const max = Math.max(...range3);
    return max - min;
  }
  /**
   * Calculates the available range with an additional "bleed" beyond the canvas that encompasses the full axis when
   * the visible range is only a portion of the axis.
   */
  calculateRangeWithBleed() {
    const { visibleRange } = this;
    const visibleScale = 1 / (visibleRange[1] - visibleRange[0]);
    return round(this.calculateAvailableRange() * visibleScale, 2);
  }
  calculateDomain() {
    if (this.linkedTo) {
      this.dataDomain = this.linkedTo.dataDomain;
    } else {
      const visibleSeries = this.boundSeries.filter((s) => this.includeInvisibleDomains || s.isEnabled());
      const domains = visibleSeries.flatMap((series) => series.getDomain(this.direction));
      const { domain, clipped } = this.normaliseDataDomain(domains);
      this.dataDomain = { domain: this.reverse ? [...domain].reverse() : domain, clipped };
    }
  }
  getAxisTransform() {
    return {
      rotation: toRadians(this.rotation),
      rotationCenterX: 0,
      rotationCenterY: 0,
      translationX: Math.floor(this.translation.x),
      translationY: Math.floor(this.translation.y)
    };
  }
  updatePosition() {
    const { crossLineGroup, axisGroup, gridGroup, translation, gridLineGroupSelection, gridPadding, gridLength } = this;
    const { rotation } = this.calculateRotations();
    const sideFlag = this.label.getSideFlag();
    const translationX = Math.floor(translation.x);
    const translationY = Math.floor(translation.y);
    crossLineGroup.setProperties({ rotation, translationX, translationY });
    axisGroup.datum = this.getAxisTransform();
    gridGroup.setProperties({ rotation, translationX, translationY });
    gridLineGroupSelection.each((line) => {
      line.x1 = gridPadding;
      line.x2 = -sideFlag * gridLength + gridPadding;
    });
  }
  updateSecondaryAxisTicks(_primaryTickCount) {
    throw new Error("AG Charts - unexpected call to updateSecondaryAxisTicks() - check axes configuration.");
  }
  updateSelections(lineData, data, params) {
    this.lineNode.datum = lineData;
    this.gridLineGroupSelection.update(
      this.gridLength ? data : [],
      (group2) => group2.append(new Line({
        tag: 2
        /* GridLine */
      })),
      (datum) => datum.tickId
    );
    this.tickLineGroupSelection.update(
      data,
      (group2) => group2.appendChild(new Line({
        tag: 0
        /* TickLine */
      })),
      (datum) => datum.tickId
    );
    this.tickLabelGroupSelection.update(
      data.map((d) => this.getTickLabelProps(d, params)),
      (group2) => group2.appendChild(new Text({
        tag: 1
        /* TickLabel */
      })),
      (datum) => datum.tickId
    );
  }
  updateAxisLine() {
    const { line } = this;
    const strokeWidth = line.enabled ? line.width : 0;
    this.lineNode.setProperties({
      stroke: line.color,
      strokeWidth
    });
  }
  updateGridLines(sideFlag) {
    const {
      gridLine: { style, width },
      gridPadding,
      gridLength
    } = this;
    if (gridLength === 0 || style.length === 0) {
      return;
    }
    this.gridLineGroupSelection.each((line, _, index) => {
      const { stroke, lineDash } = style[index % style.length];
      line.setProperties({
        x1: gridPadding,
        x2: -sideFlag * gridLength + gridPadding,
        fill: void 0,
        stroke,
        strokeWidth: width,
        lineDash
      });
    });
  }
  updateLabels() {
    const { label } = this;
    if (!label.enabled) {
      return;
    }
    this.tickLabelGroupSelection.each((node, datum) => {
      node.setProperties(datum, [
        "fill",
        "fontFamily",
        "fontSize",
        "fontStyle",
        "fontWeight",
        "text",
        "textAlign",
        "textBaseline"
      ]);
    });
  }
  wrapLabels(tickData, index, labelProps) {
    const { parallel, maxWidth, maxHeight } = this.label;
    let defaultMaxWidth = this.maxThickness;
    let defaultMaxHeight = Math.round(this.calculateAvailableRange() / tickData.labelCount);
    if (parallel) {
      [defaultMaxWidth, defaultMaxHeight] = [defaultMaxHeight, defaultMaxWidth];
    }
    tickData.ticks.forEach((tickDatum) => {
      const { text } = Text.wrap(
        tickDatum.tickLabel,
        maxWidth != null ? maxWidth : defaultMaxWidth,
        maxHeight != null ? maxHeight : defaultMaxHeight,
        labelProps,
        "hyphenate"
      );
      tickDatum.tickLabel = text;
    });
    return { tickData, index, autoRotation: 0, terminate: true };
  }
  updateTitle(params) {
    const { rotation, title, _titleCaption, lineNode, tickLineGroup, tickLabelGroup } = this;
    if (!title) {
      _titleCaption.enabled = false;
      return;
    }
    let spacing = 0;
    if (title.enabled && params.anyTickVisible) {
      const tickBBox = Group.computeBBox([tickLineGroup, tickLabelGroup, lineNode]);
      const tickWidth = rotation === 0 ? tickBBox.width : tickBBox.height;
      spacing += tickWidth + (!this.tickLabelGroup.visible ? this.seriesAreaPadding : 0);
    }
    this.setTitleProps(_titleCaption, { spacing });
  }
  // For formatting (nice rounded) tick values.
  formatTick(datum, index) {
    var _a, _b;
    const {
      label,
      labelFormatter,
      fractionDigits,
      moduleCtx: { callbackCache }
    } = this;
    if (label.formatter) {
      const value = fractionDigits > 0 ? datum : String(datum);
      return (_a = callbackCache.call(label.formatter, {
        value,
        index,
        fractionDigits,
        formatter: labelFormatter
      })) != null ? _a : value;
    } else if (labelFormatter) {
      return (_b = callbackCache.call(labelFormatter, datum)) != null ? _b : String(datum);
    }
    return String(datum);
  }
  // For formatting arbitrary values between the ticks.
  formatDatum(datum) {
    return String(datum);
  }
  computeBBox() {
    return this.axisGroup.computeBBox();
  }
  initCrossLine(crossLine) {
    crossLine.scale = this.scale;
    crossLine.gridLength = this.gridLength;
  }
  isAnySeriesActive() {
    return this.boundSeries.some((s) => this.includeInvisibleDomains || s.isEnabled());
  }
  clipTickLines(x, y, width, height) {
    this.tickLineGroup.setClipRectInGroupCoordinateSpace(new BBox(x, y, width, height));
  }
  clipGrid(x, y, width, height) {
    this.gridGroup.setClipRectInGroupCoordinateSpace(new BBox(x, y, width, height));
  }
  calculatePadding(min, _max, reverse) {
    const start = reverse ? _max : min;
    return [Math.abs(start * 0.01), Math.abs(start * 0.01)];
  }
  getTitleFormatterParams() {
    var _a;
    const boundSeries = this.boundSeries.reduce((acc, next) => {
      const keys = next.getKeys(this.direction);
      const names = next.getNames(this.direction);
      for (let idx = 0; idx < keys.length; idx++) {
        acc.push({ key: keys[idx], name: names[idx] });
      }
      return acc;
    }, []);
    return {
      direction: this.direction,
      boundSeries,
      defaultValue: (_a = this.title) == null ? void 0 : _a.text
    };
  }
  normaliseDataDomain(d) {
    return { domain: d, clipped: false };
  }
  getLayoutState() {
    return __spreadValues({
      rect: this.computeBBox(),
      gridPadding: this.gridPadding,
      seriesAreaPadding: this.seriesAreaPadding,
      tickSize: this.getTickSize()
    }, this.layout);
  }
  getModuleMap() {
    return this.moduleMap;
  }
  createModuleContext() {
    var _a;
    (_a = this.axisContext) != null ? _a : this.axisContext = this.createAxisContext();
    return __spreadProps(__spreadValues({}, this.moduleCtx), { parent: this.axisContext });
  }
  createAxisContext() {
    return {
      axisId: this.id,
      direction: this.direction,
      continuous: ContinuousScale.is(this.scale),
      keys: () => this.boundSeries.flatMap((s) => s.getKeys(this.direction)),
      scaleValueFormatter: (specifier) => {
        var _a, _b;
        return (_b = (_a = this.scale).tickFormat) == null ? void 0 : _b.call(_a, { specifier });
      },
      scaleBandwidth: () => {
        var _a;
        return (_a = this.scale.bandwidth) != null ? _a : 0;
      },
      scaleConvert: (val) => this.scale.convert(val),
      scaleInvert: (val) => {
        var _a, _b;
        return (_b = (_a = this.scale).invert) == null ? void 0 : _b.call(_a, val);
      }
    };
  }
  animateReadyUpdate(diff2) {
    const { animationManager } = this.moduleCtx;
    const selectionCtx = prepareAxisAnimationContext(this);
    const fns = prepareAxisAnimationFunctions(selectionCtx);
    fromToMotion(this.id, "axis-group", animationManager, [this.axisGroup], fns.group);
    fromToMotion(this.id, "line", animationManager, [this.lineNode], fns.line);
    fromToMotion(
      this.id,
      "line-paths",
      animationManager,
      [this.gridLineGroupSelection, this.tickLineGroupSelection],
      fns.tick,
      (_, d) => d.tickId,
      diff2
    );
    fromToMotion(
      this.id,
      "tick-labels",
      animationManager,
      [this.tickLabelGroupSelection],
      fns.label,
      (_, d) => d.tickId,
      diff2
    );
  }
  resetSelectionNodes() {
    const { gridLineGroupSelection, tickLineGroupSelection, tickLabelGroupSelection, lineNode } = this;
    const selectionCtx = prepareAxisAnimationContext(this);
    resetMotion([this.axisGroup], resetAxisGroupFn());
    resetMotion([gridLineGroupSelection, tickLineGroupSelection], resetAxisSelectionFn(selectionCtx));
    resetMotion([tickLabelGroupSelection], resetAxisLabelSelectionFn());
    resetMotion([lineNode], resetAxisLineSelectionFn());
  }
  calculateUpdateDiff(previous, tickData) {
    const added = /* @__PURE__ */ new Set();
    const removed = /* @__PURE__ */ new Set();
    const tickMap = {};
    const tickCount = Math.max(previous.length, tickData.ticks.length);
    for (let i = 0; i < tickCount; i++) {
      const tickDatum = tickData.ticks[i];
      const prev = previous[i];
      const tick = tickDatum == null ? void 0 : tickDatum.tickId;
      tickMap[tick != null ? tick : prev] = tickDatum;
      if (prev === tick) {
        continue;
      }
      if (removed.has(tick)) {
        removed.delete(tick);
      } else if (tick) {
        added.add(tick);
      }
      if (added.has(prev)) {
        added.delete(prev);
      } else if (prev) {
        removed.add(prev);
      }
    }
    return {
      changed: added.size > 0 || removed.size > 0,
      added: [...added.values()],
      removed: [...removed.values()]
    };
  }
  isReversed() {
    return !!this.reverse;
  }
};
_Axis.defaultTickMinSpacing = 50;
__decorateClass([
  Validate(BOOLEAN)
], _Axis.prototype, "nice", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], _Axis.prototype, "reverse", 2);
__decorateClass([
  Validate(STRING_ARRAY)
], _Axis.prototype, "keys", 2);
__decorateClass([
  Validate(predicateWithMessage((title) => typeof title == "object", "Title object"), { optional: true })
], _Axis.prototype, "title", 2);
var Axis = _Axis;
var CartesianAxisLabel = class extends AxisLabel {
  constructor() {
    super(...arguments);
    this.autoRotateAngle = 335;
  }
};
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], CartesianAxisLabel.prototype, "autoRotate", 2);
__decorateClass([
  Validate(DEGREE)
], CartesianAxisLabel.prototype, "autoRotateAngle", 2);
var CartesianAxis = class extends Axis {
  constructor() {
    super(...arguments);
    this.thickness = 0;
    this.position = "left";
  }
  get direction() {
    return ["top", "bottom"].includes(this.position) ? "x" : "y";
  }
  updateDirection() {
    switch (this.position) {
      case "top":
        this.rotation = -90;
        this.label.mirrored = true;
        this.label.parallel = true;
        break;
      case "right":
        this.rotation = 0;
        this.label.mirrored = true;
        this.label.parallel = false;
        break;
      case "bottom":
        this.rotation = -90;
        this.label.mirrored = false;
        this.label.parallel = true;
        break;
      case "left":
        this.rotation = 0;
        this.label.mirrored = false;
        this.label.parallel = false;
        break;
    }
    if (this.axisContext) {
      this.axisContext.position = this.position;
      this.axisContext.direction = this.direction;
    }
  }
  update(primaryTickCount) {
    this.updateDirection();
    return super.update(primaryTickCount);
  }
  calculateLayout(primaryTickCount) {
    this.updateDirection();
    return super.calculateLayout(primaryTickCount);
  }
  createAxisContext() {
    return __spreadProps(__spreadValues({}, super.createAxisContext()), {
      position: this.position
    });
  }
  assignCrossLineArrayConstructor(crossLines) {
    assignJsonApplyConstructedArray(crossLines, CartesianCrossLine);
  }
  createLabel() {
    return new CartesianAxisLabel();
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER)
], CartesianAxis.prototype, "thickness", 2);
__decorateClass([
  Validate(POSITION)
], CartesianAxis.prototype, "position", 2);
var CategoryAxis = class extends CartesianAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new BandScale());
    this._paddingOverrideEnabled = false;
    this.groupPaddingInner = 0.1;
    this.includeInvisibleDomains = true;
  }
  set paddingInner(value) {
    this._paddingOverrideEnabled = true;
    this.scale.paddingInner = value;
  }
  get paddingInner() {
    this._paddingOverrideEnabled = true;
    return this.scale.paddingInner;
  }
  set paddingOuter(value) {
    this.scale.paddingOuter = value;
  }
  get paddingOuter() {
    return this.scale.paddingOuter;
  }
  normaliseDataDomain(d) {
    const domain = [];
    const uniqueValues = /* @__PURE__ */ new Set();
    for (const v of d) {
      const key = v instanceof Date ? v.getTime() : v;
      if (!uniqueValues.has(key)) {
        uniqueValues.add(key);
        domain.push(v);
      }
    }
    return { domain, clipped: false };
  }
  calculateDomain() {
    if (!this._paddingOverrideEnabled) {
      const paddings = this.boundSeries.map((s) => {
        var _a;
        return (_a = s.getBandScalePadding) == null ? void 0 : _a.call(s);
      }).filter((p) => p != null);
      if (paddings.length > 0) {
        this.scale.paddingInner = Math.min(...paddings.map((p) => p.inner));
        this.scale.paddingOuter = Math.max(...paddings.map((p) => p.outer));
      }
    }
    return super.calculateDomain();
  }
};
CategoryAxis.className = "CategoryAxis";
CategoryAxis.type = "category";
__decorateClass([
  Validate(RATIO)
], CategoryAxis.prototype, "groupPaddingInner", 2);
var TreeNode = class {
  // current number in sibling group (index)
  constructor(label = "", parent, number = 0) {
    this.x = 0;
    this.y = 0;
    this.subtreeLeft = NaN;
    this.subtreeRight = NaN;
    this.screenX = 0;
    this.screenY = 0;
    this.children = [];
    this.leafCount = 0;
    this.prelim = 0;
    this.mod = 0;
    this.ancestor = this;
    this.change = 0;
    this.shift = 0;
    this.label = label;
    this.parent = parent;
    this.depth = parent ? parent.depth + 1 : 0;
    this.number = number;
  }
  getLeftSibling() {
    return this.number > 0 && this.parent ? this.parent.children[this.number - 1] : void 0;
  }
  getLeftmostSibling() {
    return this.number > 0 && this.parent ? this.parent.children[0] : void 0;
  }
  // traverse the left contour of a subtree, return the successor of v on this contour
  nextLeft() {
    return this.children ? this.children[0] : this.thread;
  }
  // traverse the right contour of a subtree, return the successor of v on this contour
  nextRight() {
    return this.children ? this.children[this.children.length - 1] : this.thread;
  }
  getSiblings() {
    return this.parent ? this.parent.children.filter((_, i) => i !== this.number) : [];
  }
};
function ticksToTree(ticks, pad2 = true) {
  const root = new TreeNode();
  let depth = 0;
  if (pad2) {
    ticks.forEach((tick) => depth = Math.max(depth, tick.labels.length));
  }
  ticks.forEach((tick) => {
    if (pad2) {
      while (tick.labels.length < depth) {
        tick.labels.unshift("");
      }
    }
    insertTick(root, tick);
  });
  return root;
}
function insertTick(root, tick) {
  const pathParts = tick.labels.slice().reverse();
  const lastPartIndex = pathParts.length - 1;
  pathParts.forEach((pathPart, partIndex) => {
    const children = root.children;
    const existingNode = children.find((child) => child.label === pathPart);
    const isNotLeaf = partIndex !== lastPartIndex;
    if (existingNode && isNotLeaf) {
      root = existingNode;
    } else {
      const node = new TreeNode(pathPart, root);
      node.number = children.length;
      children.push(node);
      if (isNotLeaf) {
        root = node;
      }
    }
  });
}
function moveSubtree(wm, wp, shift) {
  const subtrees = wp.number - wm.number;
  const ratio = shift / subtrees;
  wp.change -= ratio;
  wp.shift += shift;
  wm.change += ratio;
  wp.prelim += shift;
  wp.mod += shift;
}
function ancestor(vim, v, defaultAncestor) {
  return v.getSiblings().indexOf(vim.ancestor) >= 0 ? vim.ancestor : defaultAncestor;
}
function executeShifts(v) {
  const children = v.children;
  if (children) {
    let shift = 0;
    let change = 0;
    for (let i = children.length - 1; i >= 0; i--) {
      const w = children[i];
      w.prelim += shift;
      w.mod += shift;
      change += w.change;
      shift += w.shift + change;
    }
  }
}
function apportion(v, defaultAncestor, distance) {
  const w = v.getLeftSibling();
  if (w) {
    let vop = v;
    let vip = v;
    let vim = w;
    let vom = vip.getLeftmostSibling();
    let sip = vip.mod;
    let sop = vop.mod;
    let sim = vim.mod;
    let som = vom.mod;
    while (vim.nextRight() && vip.nextLeft()) {
      vim = vim.nextRight();
      vip = vip.nextLeft();
      vom = vom.nextLeft();
      vop = vop.nextRight();
      vop.ancestor = v;
      const shift = vim.prelim + sim - (vip.prelim + sip) + distance;
      if (shift > 0) {
        moveSubtree(ancestor(vim, v, defaultAncestor), v, shift);
        sip += shift;
        sop += shift;
      }
      sim += vim.mod;
      sip += vip.mod;
      som += vom.mod;
      sop += vop.mod;
    }
    if (vim.nextRight() && !vop.nextRight()) {
      vop.thread = vim.nextRight();
      vop.mod += sim - sop;
    } else {
      if (vip.nextLeft() && !vom.nextLeft()) {
        vom.thread = vip.nextLeft();
        vom.mod += sip - som;
      }
      defaultAncestor = v;
    }
  }
  return defaultAncestor;
}
function firstWalk(node, distance) {
  const children = node.children;
  if (children.length) {
    let defaultAncestor = children[0];
    children.forEach((child) => {
      firstWalk(child, distance);
      defaultAncestor = apportion(child, defaultAncestor, distance);
    });
    executeShifts(node);
    const midpoint = (children[0].prelim + children[children.length - 1].prelim) / 2;
    const leftSibling = node.getLeftSibling();
    if (leftSibling) {
      node.prelim = leftSibling.prelim + distance;
      node.mod = node.prelim - midpoint;
    } else {
      node.prelim = midpoint;
    }
  } else {
    const leftSibling = node.getLeftSibling();
    node.prelim = leftSibling ? leftSibling.prelim + distance : 0;
  }
}
var Dimensions = class {
  constructor() {
    this.top = Infinity;
    this.right = -Infinity;
    this.bottom = -Infinity;
    this.left = Infinity;
  }
  update(node, xy) {
    const { x, y } = xy(node);
    if (x > this.right) {
      this.right = x;
    }
    if (x < this.left) {
      this.left = x;
    }
    if (y > this.bottom) {
      this.bottom = y;
    }
    if (y < this.top) {
      this.top = y;
    }
  }
};
function secondWalk(v, m, layout) {
  v.x = v.prelim + m;
  v.y = v.depth;
  layout.update(v);
  v.children.forEach((w) => secondWalk(w, m + v.mod, layout));
}
function thirdWalk(v) {
  const children = v.children;
  let leafCount = 0;
  children.forEach((w) => {
    thirdWalk(w);
    if (w.children.length) {
      leafCount += w.leafCount;
    } else {
      leafCount++;
    }
  });
  v.leafCount = leafCount;
  if (children.length) {
    v.subtreeLeft = children[0].subtreeLeft;
    v.subtreeRight = children[v.children.length - 1].subtreeRight;
    v.x = (v.subtreeLeft + v.subtreeRight) / 2;
  } else {
    v.subtreeLeft = v.x;
    v.subtreeRight = v.x;
  }
}
function treeLayout(root) {
  const layout = new TreeLayout();
  firstWalk(root, 1);
  secondWalk(root, -root.prelim, layout);
  thirdWalk(root);
  return layout;
}
var TreeLayout = class {
  constructor() {
    this.dimensions = new Dimensions();
    this.leafCount = 0;
    this.nodes = [];
    this.leafNodes = [];
    this.nonLeafNodes = [];
    this.depth = 0;
  }
  update(node) {
    this.dimensions.update(node, (node2) => ({ x: node2.x, y: node2.y }));
    if (!node.children.length) {
      this.leafCount++;
      this.leafNodes.push(node);
    } else {
      this.nonLeafNodes.push(node);
    }
    if (node.depth > this.depth) {
      this.depth = node.depth;
    }
    this.nodes.push(node);
  }
  resize(width, height, shiftX = 0, shiftY = 0, flipX = false) {
    const xSteps = this.leafCount - 1;
    const ySteps = this.depth;
    const dimensions = this.dimensions;
    let scalingX = 1;
    let scalingY = 1;
    if (width > 0 && xSteps) {
      const existingSpacingX = (dimensions.right - dimensions.left) / xSteps;
      const desiredSpacingX = width / xSteps;
      scalingX = desiredSpacingX / existingSpacingX;
      if (flipX) {
        scalingX = -scalingX;
      }
    }
    if (height > 0 && ySteps) {
      const existingSpacingY = (dimensions.bottom - dimensions.top) / ySteps;
      const desiredSpacingY = height / ySteps;
      scalingY = desiredSpacingY / existingSpacingY;
    }
    const screenDimensions = new Dimensions();
    this.nodes.forEach((node) => {
      node.screenX = node.x * scalingX;
      node.screenY = node.y * scalingY;
      screenDimensions.update(node, (node2) => ({ x: node2.screenX, y: node2.screenY }));
    });
    const offsetX = -screenDimensions.left;
    const offsetY = -screenDimensions.top;
    this.nodes.forEach((node) => {
      node.screenX += offsetX + shiftX;
      node.screenY += offsetY + shiftY;
    });
  }
};
var GroupedCategoryAxisLabel = class extends AxisLabel {
  constructor() {
    super(...arguments);
    this.grid = false;
  }
};
__decorateClass([
  Validate(BOOLEAN)
], GroupedCategoryAxisLabel.prototype, "grid", 2);
var GroupedCategoryAxis = class extends CartesianAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new BandScale());
    this.tickScale = new BandScale();
    this.line = new AxisLine();
    this.label = new GroupedCategoryAxisLabel();
    this.labelColor = "rgba(87, 87, 87, 1)";
    this.includeInvisibleDomains = true;
    const { tickLineGroup, tickLabelGroup, gridLineGroup, tickScale, scale: scale2 } = this;
    scale2.paddingOuter = 0.1;
    scale2.paddingInner = scale2.paddingOuter * 2;
    this.range = scale2.range.slice();
    this.refreshScale();
    tickScale.paddingInner = 1;
    tickScale.paddingOuter = 0;
    this.gridLineSelection = Selection.select(gridLineGroup, Line);
    this.axisLineSelection = Selection.select(tickLineGroup, Line);
    this.separatorSelection = Selection.select(tickLineGroup, Line);
    this.labelSelection = Selection.select(tickLabelGroup, Text);
  }
  updateRange() {
    const { range: rr, visibleRange: vr, scale: scale2 } = this;
    const span = (rr[1] - rr[0]) / (vr[1] - vr[0]);
    const shift = span * vr[0];
    const start = rr[0] - shift;
    this.tickScale.range = scale2.range = [start, start + span];
    this.resizeTickTree();
  }
  resizeTickTree() {
    var _a;
    const s = this.scale;
    const range3 = s.domain.length ? [s.convert(s.domain[0]), s.convert(s.domain[s.domain.length - 1])] : s.range;
    const layout = this.tickTreeLayout;
    const lineHeight = this.lineHeight;
    if (layout) {
      layout.resize(
        Math.abs(range3[1] - range3[0]),
        layout.depth * lineHeight,
        (Math.min(range3[0], range3[1]) || 0) + ((_a = s.bandwidth) != null ? _a : 0) / 2,
        -layout.depth * lineHeight,
        range3[1] - range3[0] < 0
      );
    }
  }
  get lineHeight() {
    return this.label.fontSize * 1.5;
  }
  /**
   * The length of the grid. The grid is only visible in case of a non-zero value.
   */
  set gridLength(value) {
    if (this._gridLength && !value || !this._gridLength && value) {
      this.gridLineSelection.clear();
      this.labelSelection.clear();
    }
    this._gridLength = value;
  }
  get gridLength() {
    return this._gridLength;
  }
  calculateDomain() {
    var _a;
    const { direction } = this;
    const domains = [];
    let isNumericX;
    this.boundSeries.filter((s) => s.visible).forEach((series) => {
      if (direction === "x") {
        if (isNumericX === void 0) {
          const domain2 = series.getDomain(direction);
          domains.push(domain2);
          isNumericX = typeof domain2[0] === "number";
        } else if (isNumericX) {
          domains.push(series.getDomain(direction));
        }
      } else {
        domains.push(series.getDomain(direction));
      }
    });
    const domain = new Array().concat(...domains);
    const domainExtent = (_a = extent(domain)) != null ? _a : domain;
    const values = this.reverse ? [...domainExtent].reverse() : domainExtent;
    const { domain: normalisedDataDomain, clipped } = this.normaliseDataDomain(values);
    this.dataDomain = {
      domain: normalisedDataDomain,
      clipped
    };
    this.scale.domain = normalisedDataDomain;
  }
  normaliseDataDomain(d) {
    const values = d.filter((s, i, arr) => arr.indexOf(s) === i);
    const tickTree = ticksToTree(values);
    this.tickTreeLayout = treeLayout(tickTree);
    const tickScaleDomain = values.slice();
    tickScaleDomain.push("");
    this.tickScale.domain = tickScaleDomain;
    this.resizeTickTree();
    return { domain: values, clipped: false };
  }
  /**
   * Creates/removes/updates the scene graph nodes that constitute the axis.
   * Supposed to be called _manually_ after changing _any_ of the axis properties.
   * This allows to bulk set axis properties before updating the nodes.
   * The node changes made by this method are rendered on the next animation frame.
   * We could schedule this method call automatically on the next animation frame
   * when any of the axis properties change (the way we do when properties of scene graph's
   * nodes change), but this will mean that we first wait for the next animation
   * frame to make changes to the nodes of the axis, then wait for another animation
   * frame to render those changes. It's nice to have everything update automatically,
   * but this extra level of async indirection will not just introduce an unwanted delay,
   * it will also make it harder to reason about the program.
   */
  update() {
    if (!this.computedLayout) {
      return;
    }
    this.updatePosition();
    this.updateTitleCaption();
    this.updateCategoryLabels();
    this.updateSeparators();
    this.updateAxisLines();
    this.updateCategoryGridLines();
    this.resetSelectionNodes();
    return void 0;
  }
  updateTitleCaption() {
    const { _titleCaption } = this;
    _titleCaption.node.visible = false;
  }
  updateCategoryLabels() {
    if (!this.computedLayout)
      return;
    const { tickLabelLayout } = this.computedLayout;
    const labelSelection = this.labelSelection.update(tickLabelLayout);
    labelSelection.each((node, datum) => {
      node.setProperties(datum);
    });
  }
  updateSeparators() {
    if (!this.computedLayout)
      return;
    const { separatorLayout } = this.computedLayout;
    const { range: range3 } = this;
    const epsilon2 = 1e-7;
    const separatorSelection = this.separatorSelection.update(separatorLayout);
    separatorSelection.each((line, datum) => {
      line.x1 = datum.x1;
      line.x2 = datum.x2;
      line.y1 = datum.y;
      line.y2 = datum.y;
      line.visible = datum.y >= range3[0] - epsilon2 && datum.y <= range3[1] + epsilon2;
      line.stroke = this.tick.color;
      line.fill = void 0;
      line.strokeWidth = 1;
    });
  }
  updateAxisLines() {
    if (!this.computedLayout)
      return;
    const { axisLineLayout } = this.computedLayout;
    const axisLineSelection = this.axisLineSelection.update(axisLineLayout);
    axisLineSelection.each((line, datum) => {
      line.setProperties(__spreadProps(__spreadValues({}, datum), {
        stroke: this.line.color,
        strokeWidth: this.line.width
      }));
      line.x1 = datum.x;
      line.x2 = datum.x;
      line.y1 = datum.y1;
      line.y2 = datum.y2;
      line.strokeWidth = this.line.width;
      line.stroke = this.line.color;
    });
  }
  updateCategoryGridLines() {
    const { gridLength, gridLine, label, range: range3, tickScale } = this;
    const ticks = tickScale.ticks();
    const sideFlag = label.getSideFlag();
    const gridSelection = this.gridLineSelection.update(gridLength ? ticks : []);
    if (gridLength) {
      const { width, style } = gridLine;
      const styleCount = style.length;
      gridSelection.each((line, datum, index) => {
        const y = Math.round(tickScale.convert(datum));
        line.x1 = 0;
        line.x2 = -sideFlag * gridLength;
        line.y1 = y;
        line.y2 = y;
        line.visible = y >= range3[0] && y <= range3[1];
        const { stroke, lineDash } = style[index % styleCount];
        line.stroke = stroke;
        line.strokeWidth = width;
        line.lineDash = lineDash;
        line.fill = void 0;
      });
    }
  }
  computeLayout() {
    this.updateDirection();
    this.calculateDomain();
    this.updateRange();
    const {
      scale: scale2,
      label,
      label: { parallel },
      moduleCtx: { callbackCache },
      range: range3,
      title,
      title: { formatter = (p) => p.defaultValue } = {}
    } = this;
    const rangeStart = scale2.range[0];
    const rangeEnd = scale2.range[1];
    const rangeLength = Math.abs(rangeEnd - rangeStart);
    const bandwidth = rangeLength / scale2.domain.length || 0;
    const rotation = toRadians(this.rotation);
    const isHorizontal = Math.abs(Math.cos(rotation)) < 1e-8;
    const sideFlag = label.getSideFlag();
    const lineHeight = this.lineHeight;
    const tickTreeLayout = this.tickTreeLayout;
    const labels = scale2.ticks();
    const treeLabels = tickTreeLayout ? tickTreeLayout.nodes : [];
    const isLabelTree = tickTreeLayout ? tickTreeLayout.depth > 1 : false;
    const { defaultRotation, configuredRotation, parallelFlipFlag } = calculateLabelRotation({
      rotation: label.rotation,
      parallel,
      regularFlipRotation: normalizeAngle360(rotation - Math.PI / 2),
      parallelFlipRotation: normalizeAngle360(rotation)
    });
    const tickLabelLayout = [];
    const copyLabelProps = (node) => {
      return {
        fill: node.fill,
        fontFamily: node.fontFamily,
        fontSize: node.fontSize,
        fontStyle: node.fontStyle,
        fontWeight: node.fontWeight,
        rotation: node.rotation,
        rotationCenterX: node.rotationCenterX,
        rotationCenterY: node.rotationCenterY,
        text: node.text,
        textAlign: node.textAlign,
        textBaseline: node.textBaseline,
        translationX: node.translationX,
        translationY: node.translationY,
        visible: node.visible,
        x: node.x,
        y: node.y
      };
    };
    const labelBBoxes = /* @__PURE__ */ new Map();
    let maxLeafLabelWidth = 0;
    const tempText = new Text();
    const setLabelProps = (datum, index) => {
      var _a;
      tempText.setProperties({
        fill: label.color,
        fontFamily: label.fontFamily,
        fontSize: label.fontSize,
        fontStyle: label.fontStyle,
        fontWeight: label.fontWeight,
        textAlign: "center",
        textBaseline: parallelFlipFlag === -1 ? "bottom" : "hanging",
        translationX: datum.screenY - label.fontSize * 0.25,
        translationY: datum.screenX
      });
      if (index === 0) {
        const isCaptionEnabled = (title == null ? void 0 : title.enabled) && labels.length > 0;
        if (!isCaptionEnabled) {
          return false;
        }
        const text = callbackCache.call(formatter, this.getTitleFormatterParams());
        tempText.setProperties({
          fill: title.color,
          fontFamily: title.fontFamily,
          fontSize: title.fontSize,
          fontStyle: title.fontStyle,
          fontWeight: title.fontWeight,
          text,
          textBaseline: "hanging",
          translationX: datum.screenY - label.fontSize * 0.25,
          translationY: datum.screenX
        });
      } else {
        const isInRange = datum.screenX >= range3[0] && datum.screenX <= range3[1];
        if (!isInRange) {
          return false;
        }
        if (label.formatter) {
          tempText.text = (_a = callbackCache.call(label.formatter, {
            value: String(datum.label),
            index
          })) != null ? _a : String(datum.label);
        } else {
          tempText.text = String(datum.label);
        }
      }
      return true;
    };
    treeLabels.forEach((datum, index) => {
      const isVisible = setLabelProps(datum, index);
      if (isVisible) {
        const bbox2 = tempText.computeTransformedBBox();
        if (bbox2) {
          labelBBoxes.set(index, bbox2);
          const isLeaf = !datum.children.length;
          if (isLeaf && bbox2.width > maxLeafLabelWidth) {
            maxLeafLabelWidth = bbox2.width;
          }
        }
      }
    });
    const labelX = sideFlag * label.padding;
    const labelGrid = this.label.grid;
    const separatorData = [];
    treeLabels.forEach((datum, index) => {
      let visible = setLabelProps(datum, index);
      const id = index;
      tempText.x = labelX;
      tempText.rotationCenterX = labelX;
      const isLeaf = !datum.children.length;
      if (isLeaf) {
        tempText.rotation = configuredRotation;
        tempText.textAlign = "end";
        tempText.textBaseline = "middle";
        const bbox2 = labelBBoxes.get(id);
        if (bbox2 && bbox2.height > bandwidth) {
          visible = false;
          labelBBoxes.delete(id);
        }
      } else {
        tempText.translationX -= maxLeafLabelWidth - lineHeight + this.label.padding;
        const availableRange = datum.leafCount * bandwidth;
        const bbox2 = labelBBoxes.get(id);
        if (bbox2 && bbox2.width > availableRange) {
          visible = false;
          labelBBoxes.delete(id);
        } else if (isHorizontal) {
          tempText.rotation = defaultRotation;
        } else {
          tempText.rotation = -Math.PI / 2;
        }
      }
      if (datum.parent && isLabelTree) {
        const y = isLeaf ? datum.screenX - bandwidth / 2 : datum.screenX - datum.leafCount * bandwidth / 2;
        if (isLeaf) {
          if (datum.number !== datum.children.length - 1 || labelGrid) {
            separatorData.push({
              y,
              x1: 0,
              x2: -maxLeafLabelWidth - this.label.padding * 2
            });
          }
        } else {
          const x = -maxLeafLabelWidth - this.label.padding * 2 + datum.screenY;
          separatorData.push({
            y,
            x1: x + lineHeight,
            x2: x
          });
        }
      }
      let props;
      if (visible) {
        const bbox2 = tempText.computeTransformedBBox();
        if (bbox2) {
          labelBBoxes.set(index, bbox2);
        }
        props = __spreadProps(__spreadValues({}, copyLabelProps(tempText)), { visible });
      } else {
        labelBBoxes.delete(index);
        props = { visible };
      }
      tickLabelLayout.push(props);
    });
    let minX = 0;
    separatorData.forEach((d) => minX = Math.min(minX, d.x2));
    separatorData.push({
      y: Math.max(rangeStart, rangeEnd),
      x1: 0,
      x2: minX
    });
    const separatorLayout = [];
    const separatorBoxes = [];
    const epsilon2 = 1e-7;
    separatorData.forEach((datum) => {
      if (datum.y >= range3[0] - epsilon2 && datum.y <= range3[1] + epsilon2) {
        const { x1, x2, y } = datum;
        const separatorBox = new BBox(Math.min(x1, x2), y, Math.abs(x1 - x2), 0);
        separatorBoxes.push(separatorBox);
        separatorLayout.push({ x1, x2, y });
      }
    });
    const axisLineLayout = [];
    const axisLineBoxes = [];
    const lineCount = tickTreeLayout ? tickTreeLayout.depth + 1 : 1;
    for (let i = 0; i < lineCount; i++) {
      const visible = labels.length > 0 && (i === 0 || labelGrid && isLabelTree);
      const x = i > 0 ? -maxLeafLabelWidth - this.label.padding * 2 - (i - 1) * lineHeight : 0;
      const lineBox = new BBox(x, Math.min(...range3), 0, Math.abs(range3[1] - range3[0]));
      axisLineBoxes.push(lineBox);
      axisLineLayout.push({ x, y1: range3[0], y2: range3[1], visible });
    }
    const getTransformBox = (bbox2) => {
      const matrix = new Matrix();
      const {
        rotation: axisRotation,
        translationX,
        translationY,
        rotationCenterX,
        rotationCenterY
      } = this.getAxisTransform();
      Matrix.updateTransformMatrix(matrix, 1, 1, axisRotation, translationX, translationY, {
        scalingCenterX: 0,
        scalingCenterY: 0,
        rotationCenterX,
        rotationCenterY
      });
      return matrix.transformBBox(bbox2);
    };
    const bbox = BBox.merge([...labelBBoxes.values(), ...separatorBoxes, ...axisLineBoxes]);
    const transformedBBox = getTransformBox(bbox);
    return {
      bbox: transformedBBox,
      tickLabelLayout,
      separatorLayout,
      axisLineLayout
    };
  }
  calculateLayout() {
    const { axisLineLayout, separatorLayout, tickLabelLayout, bbox } = this.computeLayout();
    this.computedLayout = {
      axisLineLayout,
      separatorLayout,
      tickLabelLayout
    };
    return { bbox, primaryTickCount: void 0 };
  }
};
GroupedCategoryAxis.className = "GroupedCategoryAxis";
GroupedCategoryAxis.type = "grouped-category";
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], GroupedCategoryAxis.prototype, "labelColor", 2);
function sleep(sleepTimeoutMs) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(void 0), sleepTimeoutMs);
  });
}
var CallbackCache = class {
  constructor() {
    this.cache = /* @__PURE__ */ new WeakMap();
  }
  call(fn, ...params) {
    let serialisedParams;
    let paramCache = this.cache.get(fn);
    const invoke = () => {
      try {
        const result = fn(...params);
        if (paramCache && serialisedParams != null) {
          paramCache.set(serialisedParams, result);
        }
        return result;
      } catch (e) {
        Logger.warnOnce(`User callback errored, ignoring`, e);
        return void 0;
      }
    };
    try {
      serialisedParams = JSON.stringify(params);
    } catch (e) {
      return invoke();
    }
    if (paramCache == null) {
      paramCache = /* @__PURE__ */ new Map();
      this.cache.set(fn, paramCache);
    }
    if (!paramCache.has(serialisedParams)) {
      return invoke();
    }
    return paramCache.get(serialisedParams);
  }
  invalidateCache() {
    this.cache = /* @__PURE__ */ new WeakMap();
  }
};
var Mutex = class {
  constructor() {
    this.available = true;
    this.acquireQueue = [];
  }
  acquire(cb) {
    return new Promise((resolve) => {
      this.acquireQueue.push([cb, resolve]);
      if (this.available) {
        this.dispatchNext();
      }
    });
  }
  acquireImmediately(cb) {
    return __async(this, null, function* () {
      if (!this.available) {
        return false;
      }
      yield this.acquire(cb);
      return true;
    });
  }
  waitForClearAcquireQueue() {
    return __async(this, null, function* () {
      return this.acquire(() => __async(this, null, function* () {
        return void 0;
      }));
    });
  }
  dispatchNext() {
    return __async(this, null, function* () {
      var _a, _b;
      this.available = false;
      let [next, done] = (_a = this.acquireQueue.shift()) != null ? _a : [];
      while (next) {
        try {
          yield next();
          done == null ? void 0 : done();
        } catch (error) {
          Logger.error("mutex callback error", error);
          done == null ? void 0 : done();
        }
        [next, done] = (_b = this.acquireQueue.shift()) != null ? _b : [];
      }
      this.available = true;
    });
  }
};
var Observable = class {
  constructor() {
    this.eventListeners = /* @__PURE__ */ new Map();
  }
  addEventListener(eventType, listener) {
    if (typeof listener !== "function") {
      throw new Error("AG Charts - listener must be a Function");
    }
    const eventTypeListeners = this.eventListeners.get(eventType);
    if (eventTypeListeners) {
      eventTypeListeners.add(listener);
    } else {
      this.eventListeners.set(eventType, /* @__PURE__ */ new Set([listener]));
    }
  }
  removeEventListener(type, listener) {
    var _a;
    (_a = this.eventListeners.get(type)) == null ? void 0 : _a.delete(listener);
    if (this.eventListeners.size === 0) {
      this.eventListeners.delete(type);
    }
  }
  hasEventListener(type) {
    return this.eventListeners.has(type);
  }
  clearEventListeners() {
    this.eventListeners.clear();
  }
  fireEvent(event) {
    var _a;
    (_a = this.eventListeners.get(event.type)) == null ? void 0 : _a.forEach((listener) => listener(event));
  }
};
function debouncedAnimationFrame(cb) {
  return buildScheduler((cb2, _delayMs) => requestAnimationFrame(cb2), cb);
}
function debouncedCallback(cb) {
  return buildScheduler((cb2, delayMs = 0) => setTimeout(cb2, delayMs), cb);
}
function buildScheduler(scheduleFn, cb) {
  let scheduleCount = 0;
  let promiseRunning = false;
  let awaitingPromise;
  let awaitingDone;
  const busy = () => {
    return promiseRunning;
  };
  const done = () => {
    promiseRunning = false;
    awaitingDone == null ? void 0 : awaitingDone();
    awaitingDone = void 0;
    awaitingPromise = void 0;
    if (scheduleCount > 0) {
      scheduleFn(scheduleCb);
    }
  };
  const scheduleCb = () => {
    const count2 = scheduleCount;
    scheduleCount = 0;
    promiseRunning = true;
    const maybePromise = cb({ count: count2 });
    if (!maybePromise) {
      done();
      return;
    }
    maybePromise.then(done).catch(done);
  };
  return {
    schedule(delayMs) {
      if (scheduleCount === 0 && !busy()) {
        scheduleFn(scheduleCb, delayMs);
      }
      scheduleCount++;
    },
    await() {
      return __async(this, null, function* () {
        if (!busy()) {
          return;
        }
        if (awaitingPromise == null) {
          awaitingPromise = new Promise((resolve) => {
            awaitingDone = resolve;
          });
        }
        while (busy()) {
          yield awaitingPromise;
        }
      });
    }
  };
}
var SizeMonitor = class {
  static init(document2) {
    var _a;
    if (typeof ResizeObserver !== "undefined") {
      this.resizeObserver = new ResizeObserver((entries) => {
        for (const entry of entries) {
          const { width, height } = entry.contentRect;
          this.checkSize(this.elements.get(entry.target), entry.target, width, height);
        }
      });
    } else {
      const step = () => {
        this.elements.forEach((entry, element2) => {
          this.checkClientSize(element2, entry);
        });
      };
      this.pollerHandler = (_a = document2.defaultView) == null ? void 0 : _a.setInterval(step, 100);
    }
    this.ownerDocument = document2;
    this.ready = true;
    this.documentReady = document2.readyState !== "loading";
    if (this.documentReady)
      return;
    this.readyEventFn = () => {
      const newState = document2.readyState !== "loading";
      const oldState = this.documentReady;
      this.documentReady = newState;
      if (!newState)
        return;
      if (newState === oldState)
        return;
      for (const [el, cb] of this.queuedObserveRequests) {
        this.observe(el, cb);
      }
      this.queuedObserveRequests.length = 0;
    };
    document2.addEventListener("DOMContentLoaded", this.readyEventFn);
  }
  static destroy() {
    var _a, _b;
    if (this.pollerHandler != null) {
      clearInterval(this.pollerHandler);
      this.pollerHandler = void 0;
    }
    if (this.readyEventFn) {
      (_a = this.ownerDocument) == null ? void 0 : _a.removeEventListener("DOMContentLoaded", this.readyEventFn);
      this.readyEventFn = void 0;
    }
    (_b = this.resizeObserver) == null ? void 0 : _b.disconnect();
    this.resizeObserver = void 0;
    this.ready = false;
    this.ownerDocument = void 0;
  }
  static checkSize(entry, element2, width, height) {
    if (!entry)
      return;
    if (!entry.size || width !== entry.size.width || height !== entry.size.height) {
      entry.size = { width, height };
      entry.cb(entry.size, element2);
    }
  }
  // Only a single callback is supported.
  static observe(element2, cb) {
    if (!this.ready) {
      this.init(element2.ownerDocument);
    }
    if (!this.documentReady) {
      this.queuedObserveRequests.push([element2, cb]);
      return;
    }
    this.unobserve(element2, false);
    if (this.resizeObserver) {
      this.resizeObserver.observe(element2);
    }
    this.elements.set(element2, { cb });
  }
  static unobserve(element2, cleanup = true) {
    if (this.resizeObserver) {
      this.resizeObserver.unobserve(element2);
    }
    this.elements.delete(element2);
    this.queuedObserveRequests = this.queuedObserveRequests.filter(([el]) => el === element2);
    if (cleanup && this.elements.size === 0) {
      this.destroy();
    }
  }
  static checkClientSize(element2, entry) {
    var _a, _b;
    const width = (_a = element2.clientWidth) != null ? _a : 0;
    const height = (_b = element2.clientHeight) != null ? _b : 0;
    this.checkSize(entry, element2, width, height);
  }
};
SizeMonitor.elements = /* @__PURE__ */ new Map();
SizeMonitor.ready = false;
SizeMonitor.documentReady = false;
SizeMonitor.queuedObserveRequests = [];
var ChartHighlight = class {
  constructor() {
    this.range = "tooltip";
  }
};
__decorateClass([
  Validate(UNION(["tooltip", "node"], "a range"))
], ChartHighlight.prototype, "range", 2);
var ChartUpdateType = /* @__PURE__ */ ((ChartUpdateType2) => {
  ChartUpdateType2[ChartUpdateType2["FULL"] = 0] = "FULL";
  ChartUpdateType2[ChartUpdateType2["PROCESS_DATA"] = 1] = "PROCESS_DATA";
  ChartUpdateType2[ChartUpdateType2["PERFORM_LAYOUT"] = 2] = "PERFORM_LAYOUT";
  ChartUpdateType2[ChartUpdateType2["SERIES_UPDATE"] = 3] = "SERIES_UPDATE";
  ChartUpdateType2[ChartUpdateType2["TOOLTIP_RECALCULATION"] = 4] = "TOOLTIP_RECALCULATION";
  ChartUpdateType2[ChartUpdateType2["SCENE_RENDER"] = 5] = "SCENE_RENDER";
  ChartUpdateType2[ChartUpdateType2["NONE"] = 6] = "NONE";
  return ChartUpdateType2;
})(ChartUpdateType || {});
var DataDomain = class {
  constructor(type) {
    this.type = type;
    this.continuousDomain = [Infinity, -Infinity];
    this.discreteDomain = /* @__PURE__ */ new Set();
  }
  extend(val) {
    if (this.type === "discrete") {
      this.discreteDomain.add(val);
    } else if (this.type === "continuous") {
      if (this.continuousDomain[0] > val) {
        this.continuousDomain[0] = val;
      }
      if (this.continuousDomain[1] < val) {
        this.continuousDomain[1] = val;
      }
    }
  }
  getDomain() {
    if (this.type === "discrete") {
      return this.discreteDomain;
    } else if (this.type === "continuous") {
      return this.continuousDomain;
    }
    throw new Error("AG Charts - Unsupported data domain type: " + this.type);
  }
};
function extendDomain(values, domain = [Infinity, -Infinity]) {
  for (const value of values) {
    if (typeof value !== "number") {
      continue;
    }
    if (value < domain[0]) {
      domain[0] = value;
    }
    if (value > domain[1]) {
      domain[1] = value;
    }
  }
  return domain;
}
function toKeyString(keys) {
  return keys.map((v) => {
    if (v == null) {
      return v;
    } else if (typeof v === "number" || typeof v === "string" || typeof v === "boolean") {
      return v;
    } else if (typeof v === "object") {
      return JSON.stringify(v);
    }
    return v;
  }).join("-");
}
function round2(val) {
  const accuracy = 1e4;
  if (Number.isInteger(val)) {
    return val;
  } else if (Math.abs(val) > accuracy) {
    return Math.trunc(val);
  }
  return Math.round(val * accuracy) / accuracy;
}
function fixNumericExtentInternal(extent2) {
  if (extent2 === void 0) {
    return [];
  }
  let [min, max] = extent2;
  min = +min;
  max = +max;
  if (min === 0 && max === 0) {
    return [0, 1];
  }
  if (min === Infinity && max === -Infinity) {
    return [];
  }
  if (min === Infinity) {
    min = 0;
  }
  if (max === -Infinity) {
    max = 0;
  }
  if (!(isNumber2(min) && isNumber2(max))) {
    return [];
  }
  return [min, max];
}
function fixNumericExtent(extent2, axis) {
  var _a;
  const fixedExtent = fixNumericExtentInternal(extent2);
  if (fixedExtent.length === 0) {
    return fixedExtent;
  }
  let [min, max] = fixedExtent;
  if (min === max) {
    const [paddingMin, paddingMax] = (_a = axis == null ? void 0 : axis.calculatePadding(min, max, axis.isReversed())) != null ? _a : [1, 1];
    min -= paddingMin;
    max += paddingMax;
  }
  return [min, max];
}
var INVALID_VALUE = Symbol("invalid");
var DataModel = class {
  constructor(opts) {
    const { props, mode = "standalone" } = opts;
    this.mode = mode;
    let keys = true;
    for (const next of props) {
      if (next.type === "key" && !keys) {
        throw new Error("AG Charts - internal config error: keys must come before values.");
      }
      if (next.type === "value" && keys) {
        keys = false;
      }
    }
    this.opts = __spreadValues({ dataVisible: true }, opts);
    this.keys = props.filter((def) => def.type === "key").map((def, index) => __spreadProps(__spreadValues({}, def), { index, missing: 0 }));
    this.values = props.filter((def) => def.type === "value").map((def, index) => __spreadProps(__spreadValues({}, def), { index, missing: 0 }));
    this.aggregates = props.filter((def) => def.type === "aggregate").map((def, index) => __spreadProps(__spreadValues({}, def), { index }));
    this.groupProcessors = props.filter((def) => def.type === "group-value-processor").map((def, index) => __spreadProps(__spreadValues({}, def), { index }));
    this.propertyProcessors = props.filter((def) => def.type === "property-value-processor").map((def, index) => __spreadProps(__spreadValues({}, def), { index }));
    this.reducers = props.filter((def) => def.type === "reducer").map((def, index) => __spreadProps(__spreadValues({}, def), { index }));
    this.processors = props.filter((def) => def.type === "processor").map((def, index) => __spreadProps(__spreadValues({}, def), { index }));
    for (const def of this.values) {
      if (def.property == null) {
        throw new Error(
          `AG Charts - internal config error: no properties specified for value definitions: ${JSON.stringify(
            def
          )}`
        );
      }
    }
    const verifyMatchGroupId = ({ matchGroupIds }) => {
      for (const matchGroupId of matchGroupIds != null ? matchGroupIds : []) {
        if (!this.values.some((def) => def.groupId === matchGroupId)) {
          throw new Error(
            `AG Charts - internal config error: matchGroupIds properties must match defined groups (${matchGroupId}).`
          );
        }
      }
    };
    const verifyMatchIds = ({ matchIds }) => {
      for (const matchId of matchIds != null ? matchIds : []) {
        if (!this.values.some(
          (def) => {
            var _a;
            return (_a = def.ids) == null ? void 0 : _a.some(([scope, id]) => scope === matchId[0] && id === matchId[1]);
          }
        )) {
          throw new Error(
            `AG Charts - internal config error: matchGroupIds properties must match defined groups (${matchId}).`
          );
        }
      }
    };
    for (const def of [...this.groupProcessors, ...this.aggregates]) {
      verifyMatchIds(def);
      verifyMatchGroupId(def);
    }
  }
  resolveProcessedDataIndexById(scope, searchId) {
    var _a;
    const { index, def } = (_a = this.resolveProcessedDataDefById(scope, searchId)) != null ? _a : {};
    return { index, def };
  }
  resolveProcessedDataIndicesById(scope, searchId) {
    return this.resolveProcessedDataDefsById(scope, searchId).map(({ index, def }) => ({ index, def }));
  }
  resolveProcessedDataDefById(scope, searchId) {
    return this.resolveProcessedDataDefsById(scope, searchId)[0];
  }
  resolveProcessedDataDefsByIds(scope, searchIds) {
    const defs = [];
    for (const searchId of searchIds) {
      defs.push([searchId, this.resolveProcessedDataDefsById(scope, searchId)]);
    }
    return defs;
  }
  resolveProcessedDataDefsValues(defs, { keys, values }) {
    const result = {};
    for (const [searchId, [{ index, def }]] of defs) {
      const processedData = def.type === "key" ? keys : values;
      result[searchId] = processedData[index];
    }
    return result;
  }
  resolveProcessedDataDefsById(searchScope, searchId) {
    const { keys, values, aggregates, groupProcessors, reducers } = this;
    const match = (prop) => {
      const { ids, scopes } = prop;
      if (ids == null)
        return false;
      if (searchScope != null && !(scopes == null ? void 0 : scopes.some((scope) => scope === searchScope.id)))
        return false;
      return ids.some(
        ([scope, id]) => scope === searchScope.id && (typeof searchId === "string" ? id === searchId : searchId.test(id))
      );
    };
    const allDefs = [
      keys,
      values,
      aggregates,
      groupProcessors,
      reducers
    ];
    const result = [];
    for (const defs of allDefs) {
      result.push(...defs.filter(match).map((def) => ({ index: def.index, def })));
    }
    if (result.length > 0) {
      return result;
    }
    throw new Error(`AG Charts - didn't find property definition for [${searchId}, ${searchScope.id}]`);
  }
  getDomain(scope, searchId, type = "value", processedData) {
    var _a, _b, _c, _d;
    let matches;
    try {
      matches = this.resolveProcessedDataIndicesById(scope, searchId);
    } catch (e) {
      if (typeof searchId !== "string" && /didn't find property definition/.test(e.message))
        return [];
      throw e;
    }
    let domainProp;
    switch (type) {
      case "key":
        domainProp = "keys";
        break;
      case "value":
        domainProp = "values";
        break;
      case "aggregate":
        domainProp = "aggValues";
        break;
      case "group-value-processor":
        domainProp = "groups";
        break;
      default:
        return [];
    }
    const firstMatch = (_b = (_a = processedData.domain[domainProp]) == null ? void 0 : _a[matches[0].index]) != null ? _b : [];
    if (matches.length === 1) {
      return firstMatch;
    }
    const result = [...firstMatch];
    for (const idx of matches.slice(1)) {
      extendDomain((_d = (_c = processedData.domain[domainProp]) == null ? void 0 : _c[idx.index]) != null ? _d : [], result);
    }
    return result;
  }
  processData(data, sources) {
    const {
      opts: { groupByKeys, groupByFn },
      aggregates,
      groupProcessors,
      reducers,
      processors,
      propertyProcessors
    } = this;
    const start = performance.now();
    for (const def of [...this.keys, ...this.values]) {
      def.missing = 0;
    }
    if (groupByKeys && this.keys.length === 0) {
      return void 0;
    }
    let processedData = this.extractData(data, sources);
    if (groupByKeys) {
      processedData = this.groupData(processedData);
    } else if (groupByFn) {
      processedData = this.groupData(processedData, groupByFn(processedData));
    }
    if (groupProcessors.length > 0) {
      this.postProcessGroups(processedData);
    }
    if (aggregates.length > 0) {
      this.aggregateData(processedData);
    }
    if (propertyProcessors.length > 0) {
      this.postProcessProperties(processedData);
    }
    if (reducers.length > 0) {
      this.reduceData(processedData);
    }
    if (processors.length > 0) {
      this.postProcessData(processedData);
    }
    for (const def of [...this.keys, ...this.values]) {
      if (data.length > 0 && def.missing >= data.length) {
        Logger.warnOnce(`the key '${def.property}' was not found in any data element.`);
      }
    }
    const end = performance.now();
    processedData.time = end - start;
    if (Debug.check(true, "data-model")) {
      logProcessedData(processedData);
    }
    return processedData;
  }
  valueGroupIdxLookup({ matchGroupIds, matchIds }) {
    return this.values.map((def, index) => ({ def, index })).filter(({ def }) => {
      if (matchGroupIds && (def.groupId == null || !matchGroupIds.includes(def.groupId))) {
        return false;
      }
      if (!matchIds)
        return true;
      if (def.ids == null)
        return false;
      return matchIds.some(
        ([matchScope, matchId]) => {
          var _a;
          return (_a = def.ids) == null ? void 0 : _a.some(([defScope, defId]) => defScope === matchScope && defId === matchId);
        }
      );
    }).map(({ index }) => index);
  }
  valueIdxLookup(scopes, prop) {
    const noScopesToMatch = scopes == null || scopes.length === 0;
    const scopeMatch = (compareTo) => {
      const anyScope = compareTo == null;
      if (anyScope)
        return true;
      const noScopes = compareTo == null || compareTo.length === 0;
      if (noScopesToMatch === noScopes)
        return true;
      return compareTo == null ? void 0 : compareTo.some((s) => scopes.includes(s));
    };
    const propId = typeof prop === "string" ? prop : prop.id;
    const idMatch = ([scope, id]) => {
      return scopeMatch([scope]) && id === propId;
    };
    const result = this.values.findIndex((def) => {
      var _a;
      return scopeMatch(def.scopes) && (((_a = def.ids) == null ? void 0 : _a.some((id) => idMatch(id))) || def.property === propId || def.id === propId);
    });
    if (result >= 0) {
      return result;
    }
    throw new Error(
      `AG Charts - configuration error, unknown property ${JSON.stringify(prop)} in scope(s) ${JSON.stringify(
        scopes
      )}`
    );
  }
  extractData(data, sources) {
    var _a, _b, _c, _d, _e, _f;
    const {
      keys: keyDefs,
      values: valueDefs,
      opts: { dataVisible }
    } = this;
    const { dataDomain, processValue, scopes, allScopesHaveSameDefs } = this.initDataDomainProcessor();
    const resultData = new Array(dataVisible ? data.length : 0);
    let resultDataIdx = 0;
    let partialValidDataCount = 0;
    for (const [datumIdx, datum] of data.entries()) {
      const sourceDatums = {};
      const validScopes = scopes.size > 0 ? new Set(scopes) : void 0;
      const keys = dataVisible ? new Array(keyDefs.length) : void 0;
      let keyIdx = 0;
      let key;
      for (const def of keyDefs) {
        key = processValue(def, datum, key);
        if (key === INVALID_VALUE)
          break;
        if (keys) {
          keys[keyIdx++] = key;
        }
      }
      if (key === INVALID_VALUE)
        continue;
      const values = dataVisible && valueDefs.length > 0 ? new Array(valueDefs.length) : void 0;
      let value;
      const sourcesById = {};
      for (const source of sources != null ? sources : []) {
        sourcesById[source.id] = source;
      }
      for (const [valueDefIdx, def] of valueDefs.entries()) {
        for (const scope of (_a = def.scopes) != null ? _a : scopes) {
          const source = sourcesById[scope];
          const valueDatum = (_b = source == null ? void 0 : source.data[datumIdx]) != null ? _b : datum;
          value = processValue(def, valueDatum, value);
          if (value === INVALID_VALUE || !values)
            continue;
          if (source !== void 0) {
            (_d = sourceDatums[_c = source.id]) != null ? _d : sourceDatums[_c] = {};
            sourceDatums[source.id][def.property] = value;
          }
          if (def.useScopedValues) {
            (_e = values[valueDefIdx]) != null ? _e : values[valueDefIdx] = {};
            values[valueDefIdx][scope] = value;
          } else {
            values[valueDefIdx] = value;
          }
        }
        if (value === INVALID_VALUE) {
          if (allScopesHaveSameDefs)
            break;
          for (const scope of (_f = def.scopes) != null ? _f : scopes) {
            validScopes == null ? void 0 : validScopes.delete(scope);
          }
          if ((validScopes == null ? void 0 : validScopes.size) === 0)
            break;
        }
      }
      if (value === INVALID_VALUE && allScopesHaveSameDefs)
        continue;
      if ((validScopes == null ? void 0 : validScopes.size) === 0)
        continue;
      if (dataVisible) {
        const result = {
          datum: __spreadValues(__spreadValues({}, datum), sourceDatums),
          keys,
          values
        };
        if (!allScopesHaveSameDefs && validScopes && validScopes.size < scopes.size) {
          partialValidDataCount++;
          result.validScopes = [...validScopes];
        }
        resultData[resultDataIdx++] = result;
      }
    }
    resultData.length = resultDataIdx;
    const propertyDomain = (def) => {
      const result = dataDomain.get(def).getDomain();
      if (Array.isArray(result) && result[0] > result[1]) {
        return [];
      }
      return [...result];
    };
    return {
      type: "ungrouped",
      input: { count: data.length },
      data: resultData,
      domain: {
        keys: keyDefs.map((def) => propertyDomain(def)),
        values: valueDefs.map((def) => propertyDomain(def))
      },
      defs: {
        allScopesHaveSameDefs,
        keys: keyDefs,
        values: valueDefs
      },
      partialValidDataCount,
      time: 0
    };
  }
  groupData(data, groupingFn) {
    var _a, _b, _c, _d;
    const processedData = /* @__PURE__ */ new Map();
    for (const dataEntry of data.data) {
      const { keys, values, datum, validScopes } = dataEntry;
      const group2 = groupingFn ? groupingFn(dataEntry) : keys;
      const groupStr = toKeyString(group2);
      if (processedData.has(groupStr)) {
        const existingData = processedData.get(groupStr);
        existingData.values.push(values);
        existingData.datum.push(datum);
        if (validScopes != null) {
          for (let index = 0; index < ((_b = (_a = existingData.validScopes) == null ? void 0 : _a.length) != null ? _b : 0); index++) {
            const scope = (_c = existingData.validScopes) == null ? void 0 : _c[index];
            if (validScopes.some((s) => s === scope))
              continue;
            (_d = existingData.validScopes) == null ? void 0 : _d.splice(index, 1);
          }
        }
      } else {
        processedData.set(groupStr, {
          keys: group2,
          values: [values],
          datum: [datum],
          validScopes
        });
      }
    }
    const resultData = new Array(processedData.size);
    const resultGroups = new Array(processedData.size);
    let dataIndex = 0;
    for (const [, { keys, values, datum, validScopes }] of processedData.entries()) {
      if ((validScopes == null ? void 0 : validScopes.length) === 0)
        continue;
      resultGroups[dataIndex] = keys;
      resultData[dataIndex++] = {
        keys,
        values,
        datum,
        validScopes
      };
    }
    return __spreadProps(__spreadValues({}, data), {
      type: "grouped",
      data: resultData,
      domain: __spreadProps(__spreadValues({}, data.domain), {
        groups: resultGroups
      })
    });
  }
  aggregateData(processedData) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const { aggregates: aggDefs } = this;
    if (!aggDefs)
      return;
    const resultAggValues = aggDefs.map(() => [Infinity, -Infinity]);
    const resultAggValueIndices = aggDefs.map((def) => this.valueGroupIdxLookup(def));
    const resultAggFns = aggDefs.map((def) => def.aggregateFunction);
    const resultGroupAggFns = aggDefs.map((def) => def.groupAggregateFunction);
    const resultFinalFns = aggDefs.map((def) => def.finalFunction);
    for (const group2 of processedData.data) {
      let { values } = group2;
      const { validScopes } = group2;
      (_a = group2.aggValues) != null ? _a : group2.aggValues = new Array(resultAggValueIndices.length);
      if (processedData.type === "ungrouped") {
        values = [values];
      }
      let resultIdx = 0;
      for (const indices of resultAggValueIndices) {
        const scopeValid = (_b = validScopes == null ? void 0 : validScopes.some((s) => {
          var _a2;
          return (_a2 = aggDefs[resultIdx].matchScopes) == null ? void 0 : _a2.some((as) => s === as);
        })) != null ? _b : true;
        if (!scopeValid) {
          resultIdx++;
          continue;
        }
        let groupAggValues = (_d = (_c = resultGroupAggFns[resultIdx]) == null ? void 0 : _c.call(resultGroupAggFns)) != null ? _d : extendDomain([]);
        for (const distinctValues of values) {
          const valuesToAgg = indices.map((valueIdx) => distinctValues[valueIdx]);
          const valuesAgg = resultAggFns[resultIdx](valuesToAgg, group2.keys);
          if (valuesAgg) {
            groupAggValues = (_f = (_e = resultGroupAggFns[resultIdx]) == null ? void 0 : _e.call(resultGroupAggFns, valuesAgg, groupAggValues)) != null ? _f : extendDomain(valuesAgg, groupAggValues);
          }
        }
        const finalValues = ((_h = (_g = resultFinalFns[resultIdx]) == null ? void 0 : _g.call(resultFinalFns, groupAggValues)) != null ? _h : groupAggValues).map(
          (v) => round2(v)
        );
        extendDomain(finalValues, resultAggValues[resultIdx]);
        group2.aggValues[resultIdx++] = finalValues;
      }
    }
    processedData.domain.aggValues = resultAggValues;
  }
  postProcessGroups(processedData) {
    var _a, _b, _c, _d, _e;
    const { groupProcessors } = this;
    if (!groupProcessors)
      return;
    const affectedIndices = /* @__PURE__ */ new Set();
    const updatedDomains = /* @__PURE__ */ new Map();
    const groupProcessorIndices = /* @__PURE__ */ new Map();
    const groupProcessorInitFns = /* @__PURE__ */ new Map();
    for (const processor of groupProcessors) {
      const indices = this.valueGroupIdxLookup(processor);
      groupProcessorIndices.set(processor, indices);
      groupProcessorInitFns.set(processor, processor.adjust());
      for (const idx of indices) {
        const valueDef = this.values[idx];
        affectedIndices.add(idx);
        updatedDomains.set(idx, new DataDomain(valueDef.valueType === "category" ? "discrete" : "continuous"));
      }
    }
    const updateDomains = (values) => {
      var _a2;
      for (const valueIndex of affectedIndices) {
        (_a2 = updatedDomains.get(valueIndex)) == null ? void 0 : _a2.extend(values[valueIndex]);
      }
    };
    for (const group2 of processedData.data) {
      for (const processor of groupProcessors) {
        const scopeValid = (_b = (_a = group2.validScopes) == null ? void 0 : _a.some((s) => {
          var _a2;
          return (_a2 = processor.matchScopes) == null ? void 0 : _a2.some((as) => s === as);
        })) != null ? _b : true;
        if (!scopeValid) {
          continue;
        }
        const valueIndexes = (_c = groupProcessorIndices.get(processor)) != null ? _c : [];
        const adjustFn = (_e = (_d = groupProcessorInitFns.get(processor)) == null ? void 0 : _d()) != null ? _e : () => void 0;
        if (processedData.type === "grouped") {
          for (const values of group2.values) {
            if (values) {
              adjustFn(values, valueIndexes);
            }
          }
          continue;
        }
        if (group2.values) {
          adjustFn(group2.values, valueIndexes);
        }
      }
      if (processedData.type === "grouped") {
        for (const values of group2.values) {
          updateDomains(values);
        }
      } else {
        updateDomains(group2.values);
      }
    }
    for (const [idx, dataDomain] of updatedDomains) {
      processedData.domain.values[idx] = [...dataDomain.getDomain()];
    }
  }
  postProcessProperties(processedData) {
    const { propertyProcessors } = this;
    if (!propertyProcessors)
      return;
    for (const { adjust, property, scopes } of propertyProcessors) {
      adjust()(processedData, this.valueIdxLookup(scopes != null ? scopes : [], property));
    }
  }
  reduceData(processedData) {
    var _a, _b, _c;
    const { reducers: reducerDefs } = this;
    const scopes = reducerDefs.map((def) => def.scopes);
    const reducers = reducerDefs.map((def) => def.reducer());
    const accValues = reducerDefs.map((def) => def.initialValue);
    for (const group2 of processedData.data) {
      let reducerIndex = 0;
      for (const reducer of reducers) {
        const scopeValid = (_b = (_a = group2.validScopes) == null ? void 0 : _a.some((s) => {
          var _a2;
          return (_a2 = scopes[reducerIndex]) == null ? void 0 : _a2.some((as) => s === as);
        })) != null ? _b : true;
        if (!scopeValid) {
          reducerIndex++;
          continue;
        }
        accValues[reducerIndex] = reducer(accValues[reducerIndex], group2);
        reducerIndex++;
      }
    }
    for (let accIdx = 0; accIdx < accValues.length; accIdx++) {
      (_c = processedData.reduced) != null ? _c : processedData.reduced = {};
      processedData.reduced[reducerDefs[accIdx].property] = accValues[accIdx];
    }
  }
  postProcessData(processedData) {
    var _a;
    const { processors: processorDefs } = this;
    for (const def of processorDefs) {
      (_a = processedData.reduced) != null ? _a : processedData.reduced = {};
      processedData.reduced[def.property] = def.calculate(processedData);
    }
  }
  initDataDomainProcessor() {
    var _a;
    const { keys: keyDefs, values: valueDefs } = this;
    const scopes = /* @__PURE__ */ new Set();
    for (const valueDef of valueDefs) {
      for (const scope of (_a = valueDef.scopes) != null ? _a : []) {
        scopes.add(scope);
      }
    }
    const scopesCount = scopes.size;
    const dataDomain = /* @__PURE__ */ new Map();
    const processorFns = /* @__PURE__ */ new Map();
    let allScopesHaveSameDefs = true;
    const initDataDomainKey = (key, type, updateDataDomain = dataDomain) => {
      var _a2;
      if (type === "category") {
        updateDataDomain.set(key, new DataDomain("discrete"));
      } else {
        updateDataDomain.set(key, new DataDomain("continuous"));
        allScopesHaveSameDefs && (allScopesHaveSameDefs = ((_a2 = key.scopes) != null ? _a2 : []).length === scopesCount);
      }
    };
    const initDataDomain = () => {
      keyDefs.forEach((def) => initDataDomainKey(def, def.valueType));
      valueDefs.forEach((def) => initDataDomainKey(def, def.valueType));
    };
    initDataDomain();
    const accessors = this.buildAccessors(...keyDefs, ...valueDefs);
    const processValue = (def, datum, previousDatum) => {
      var _a2, _b, _c, _d;
      const hasAccessor = def.property in accessors;
      let valueInDatum = false;
      let value;
      if (hasAccessor) {
        try {
          value = accessors[def.property](datum);
        } catch (error) {
        }
        valueInDatum = value !== void 0;
      } else {
        valueInDatum = def.property in datum;
        value = valueInDatum ? datum[def.property] : def.missingValue;
      }
      if (def.forceValue != null) {
        const valueNegative = valueInDatum && isNegative(value);
        value = valueNegative ? -1 * def.forceValue : def.forceValue;
        valueInDatum = true;
      }
      const missingValueDef = "missingValue" in def;
      if (!valueInDatum && !missingValueDef) {
        def.missing++;
      }
      if (!dataDomain.has(def)) {
        initDataDomain();
      }
      if (valueInDatum) {
        const valid = (_b = (_a2 = def.validation) == null ? void 0 : _a2.call(def, value, datum)) != null ? _b : true;
        if (!valid) {
          if ("invalidValue" in def) {
            value = def.invalidValue;
          } else {
            if (this.mode !== "integrated") {
              Logger.warnOnce(`invalid value of type [${typeof value}] ignored:`, `[${value}]`);
            }
            return INVALID_VALUE;
          }
        }
      }
      if (def.processor) {
        if (!processorFns.has(def)) {
          processorFns.set(def, def.processor());
        }
        value = (_c = processorFns.get(def)) == null ? void 0 : _c(value, previousDatum !== INVALID_VALUE ? previousDatum : void 0);
      }
      (_d = dataDomain.get(def)) == null ? void 0 : _d.extend(value);
      return value;
    };
    return { dataDomain, processValue, initDataDomain, scopes, allScopesHaveSameDefs };
  }
  buildAccessors(...defs) {
    const result = {};
    if (this.mode === "integrated")
      return result;
    for (const def of defs) {
      const isPath = def.property.indexOf(".") >= 0 || def.property.indexOf("[") >= 0;
      if (!isPath)
        continue;
      let fnBody;
      if (def.property.startsWith("[")) {
        fnBody = `return datum${def.property};`;
      } else {
        fnBody = `return datum.${def.property};`;
      }
      result[def.property] = new Function("datum", fnBody);
    }
    return result;
  }
};
function logProcessedData(processedData) {
  var _a, _b;
  const logValues = (name, data) => {
    if (data.length > 0) {
      Logger.log(`DataModel.processData() - ${name}`);
      Logger.table(data);
    }
  };
  Logger.log("DataModel.processData() - processedData", processedData);
  logValues("Key Domains", processedData.domain.keys);
  logValues("Group Domains", (_a = processedData.domain.groups) != null ? _a : []);
  logValues("Value Domains", processedData.domain.values);
  logValues("Aggregate Domains", (_b = processedData.domain.aggValues) != null ? _b : []);
  if (processedData.type === "grouped") {
    const flattenedValues = processedData.data.reduce((acc, next) => {
      var _a2, _b2;
      const keys = (_a2 = next.keys) != null ? _a2 : [];
      const aggValues = (_b2 = next.aggValues) != null ? _b2 : [];
      const skipKeys = next.keys.map(() => void 0);
      const skipAggValues = aggValues == null ? void 0 : aggValues.map(() => void 0);
      acc.push(
        ...next.values.map((v, i) => [
          ...i === 0 ? keys : skipKeys,
          ...v != null ? v : [],
          ...i == 0 ? aggValues : skipAggValues
        ])
      );
      return acc;
    }, []);
    logValues("Values", flattenedValues);
  } else {
    const flattenedValues = processedData.data.reduce((acc, next) => {
      var _a2;
      const aggValues = (_a2 = next.aggValues) != null ? _a2 : [];
      acc.push([...next.keys, ...next.values, ...aggValues]);
      return acc;
    }, []);
    logValues("Values", flattenedValues);
  }
}
var DataController = class {
  constructor(mode) {
    this.mode = mode;
    this.debug = Debug.create(true, "data-model");
    this.requested = [];
    this.status = "setup";
  }
  request(id, data, opts) {
    return __async(this, null, function* () {
      if (this.status !== "setup")
        throw new Error(`AG Charts - data request after data setup phase.`);
      return new Promise((resolve, reject) => {
        this.requested.push({
          id,
          opts,
          data,
          resultCb: resolve,
          reject
        });
      });
    });
  }
  execute() {
    return __async(this, null, function* () {
      if (this.status !== "setup")
        throw new Error(`AG Charts - data request after data setup phase.`);
      this.status = "executed";
      this.debug("DataController.execute() - requested", this.requested);
      const { valid, invalid } = this.validateRequests(this.requested);
      this.debug("DataController.execute() - validated", valid);
      const merged = this.mergeRequested(valid);
      this.debug("DataController.execute() - merged", merged);
      const debugMode = Debug.check(true, "data-model");
      if (debugMode) {
        window.processedData = [];
      }
      const multipleSources = valid.some((v) => v.data != null);
      for (const { opts, data, resultCbs, rejects, ids } of merged) {
        const needsValueExtraction = multipleSources || opts.props.some((p) => {
          var _a;
          if (p.type !== "value" && p.type !== "key")
            return false;
          return (_a = p.useScopedValues) != null ? _a : false;
        });
        try {
          const dataModel = new DataModel(__spreadProps(__spreadValues({}, opts), { mode: this.mode }));
          const processedData = dataModel.processData(data, valid);
          if (debugMode) {
            window.processedData.push(processedData);
          }
          if (processedData && processedData.partialValidDataCount === 0) {
            resultCbs.forEach((cb, requestIdx) => {
              const id = ids[requestIdx];
              let requestProcessedData = processedData;
              if (needsValueExtraction) {
                requestProcessedData = this.extractScopedData(id, processedData);
              }
              cb({ dataModel, processedData: requestProcessedData });
            });
          } else if (processedData) {
            this.splitResult(dataModel, processedData, ids, resultCbs);
          } else {
            rejects.forEach((cb) => cb(new Error(`AG Charts - no processed data generated`)));
          }
        } catch (error) {
          rejects.forEach((cb) => cb(error));
        }
      }
      invalid.forEach(({ error, reject }) => reject(error));
    });
  }
  extractScopedData(id, processedData) {
    const extractDatum = (datum) => {
      if (Array.isArray(datum)) {
        return datum.map(extractDatum);
      }
      return __spreadValues(__spreadValues({}, datum), datum[id]);
    };
    const extractValues = (values) => {
      var _a;
      if (Array.isArray(values)) {
        return values.map(extractValues);
      }
      return (_a = values == null ? void 0 : values[id]) != null ? _a : values;
    };
    return __spreadProps(__spreadValues({}, processedData), {
      data: processedData.data.map((datum) => __spreadProps(__spreadValues({}, datum), {
        datum: extractDatum(datum.datum),
        values: datum.values.map(extractValues)
      }))
    });
  }
  validateRequests(requested) {
    const valid = [];
    const invalid = [];
    for (const [index, request] of requested.entries()) {
      if (index > 0 && request.data.length !== requested[0].data.length && request.opts.groupByData === false) {
        invalid.push(__spreadProps(__spreadValues({}, request), {
          error: new Error("all series[].data arrays must be of the same length and have matching keys.")
        }));
      } else {
        valid.push(request);
      }
    }
    return { valid, invalid };
  }
  mergeRequested(requested) {
    const grouped = [];
    const keys = (props) => {
      return props.filter((p) => p.type === "key").map((p) => p.property).join(";");
    };
    const groupMatch = ({ opts, data }) => (gr) => {
      return (opts.groupByData === false || gr[0].data === data) && gr[0].opts.groupByKeys === opts.groupByKeys && gr[0].opts.dataVisible === opts.dataVisible && gr[0].opts.groupByFn === opts.groupByFn && keys(gr[0].opts.props) === keys(opts.props);
    };
    const propMatch = (prop) => (existing) => {
      var _a;
      if (existing.type !== prop.type)
        return false;
      const diff2 = (_a = jsonDiff(existing, prop)) != null ? _a : {};
      delete diff2["scopes"];
      delete diff2["id"];
      delete diff2["ids"];
      if ("useScopedValues" in diff2) {
        delete diff2["useScopedValues"];
      }
      return Object.keys(diff2).length === 0;
    };
    const updateKeyValueOpts = (prop) => {
      var _a;
      if (prop.type !== "key" && prop.type !== "value")
        return;
      const uniqueScopes = new Set((_a = prop.scopes) != null ? _a : []);
      prop.useScopedValues = uniqueScopes.size > 1;
    };
    const mergeOpts = (opts) => {
      return __spreadProps(__spreadValues({}, opts[0]), {
        props: opts.reduce((result, next) => {
          var _a, _b, _c, _d, _e, _f;
          for (const prop of next.props) {
            if (prop.id != null) {
              (_a = prop.ids) != null ? _a : prop.ids = [];
              (_b = prop.scopes) == null ? void 0 : _b.forEach((scope) => {
                var _a2;
                return (_a2 = prop.ids) == null ? void 0 : _a2.push([scope, prop.id]);
              });
            }
            const match = result.find(propMatch(prop));
            if (!match) {
              updateKeyValueOpts(prop);
              result.push(prop);
              continue;
            }
            (_c = match.scopes) != null ? _c : match.scopes = [];
            match.scopes.push(...(_d = prop.scopes) != null ? _d : []);
            updateKeyValueOpts(prop);
            if (match.type !== "key" && match.type !== "value")
              continue;
            (_f = match.ids) == null ? void 0 : _f.push(...(_e = prop.ids) != null ? _e : []);
          }
          return result;
        }, [])
      });
    };
    const merge = (props) => {
      return {
        ids: props.map(({ id }) => id),
        resultCbs: props.map(({ resultCb }) => resultCb),
        rejects: props.map(({ reject }) => reject),
        data: props[0].data,
        opts: mergeOpts(props.map(({ opts }) => opts))
      };
    };
    for (const request of requested) {
      const match = grouped.find(groupMatch(request));
      if (match) {
        match.push(request);
      } else {
        grouped.push([request]);
      }
    }
    return grouped.map(merge);
  }
  splitResult(dataModel, processedData, scopes, resultCbs) {
    for (let index = 0; index < scopes.length; index++) {
      const scope = scopes[index];
      const resultCb = resultCbs[index];
      resultCb({
        dataModel,
        processedData: __spreadProps(__spreadValues({}, processedData), {
          data: processedData.data.filter(({ validScopes }) => {
            return validScopes == null || validScopes.some((s) => s === scope);
          })
        })
      });
    }
  }
};
var Listeners = class {
  constructor() {
    this.registeredListeners = /* @__PURE__ */ new Map();
  }
  addListener(eventType, handler, meta) {
    const record = { symbol: Symbol(eventType), handler, meta };
    if (this.registeredListeners.has(eventType)) {
      this.registeredListeners.get(eventType).push(record);
    } else {
      this.registeredListeners.set(eventType, [record]);
    }
    return () => this.removeListener(record.symbol);
  }
  removeListener(eventSymbol) {
    for (const [type, listeners] of this.registeredListeners.entries()) {
      const matchIndex = listeners.findIndex((listener) => listener.symbol === eventSymbol);
      if (matchIndex >= 0) {
        listeners.splice(matchIndex, 1);
        if (listeners.length === 0) {
          this.registeredListeners.delete(type);
        }
        break;
      }
    }
  }
  dispatch(eventType, ...params) {
    for (const listener of this.getListenersByType(eventType)) {
      try {
        listener.handler(...params);
      } catch (e) {
        Logger.errorOnce(e);
      }
    }
  }
  dispatchWrapHandlers(eventType, wrapFn, ...params) {
    for (const listener of this.getListenersByType(eventType)) {
      try {
        wrapFn(listener.handler, listener.meta, ...params);
      } catch (e) {
        Logger.errorOnce(e);
      }
    }
  }
  getListenersByType(eventType) {
    var _a;
    return (_a = this.registeredListeners.get(eventType)) != null ? _a : [];
  }
};
var BaseManager = class {
  constructor() {
    this.listeners = new Listeners();
  }
  addListener(type, handler, meta) {
    return this.listeners.addListener(type, handler, meta);
  }
  removeListener(listenerSymbol) {
    this.listeners.removeListener(listenerSymbol);
  }
};
var DEBUG_SELECTORS = [true, "animation"];
var AnimationManager = class extends BaseManager {
  constructor(interactionManager, chartUpdateMutex) {
    super();
    this.interactionManager = interactionManager;
    this.chartUpdateMutex = chartUpdateMutex;
    this.defaultDuration = 1e3;
    this.batch = new AnimationBatch();
    this.debug = Debug.create(...DEBUG_SELECTORS);
    this.isPlaying = false;
    this.requestId = null;
    this.skipAnimations = false;
  }
  /**
   * Create an animation to tween a value between the `from` and `to` properties. If an animation already exists
   * with the same `id`, immediately stop it.
   */
  animate(_a) {
    var _b = _a, {
      disableInteractions = true,
      immutable = true
    } = _b, opts = __objRest(_b, [
      "disableInteractions",
      "immutable"
    ]);
    var _a2, _b2;
    const { batch } = this;
    try {
      if (opts.id != null && batch.controllers.has(opts.id)) {
        if (!immutable) {
          return batch.controllers.get(opts.id).reset(opts);
        }
        batch.controllers.get(opts.id).stop();
        this.debug(`Skipping animation batch due to update of existing animation: ${opts.id}`);
        this.batch.skip();
      }
    } catch (error) {
      this.failsafeOnError(error);
      return;
    }
    const id = (_a2 = opts.id) != null ? _a2 : Math.random().toString();
    const skip = this.isSkipped();
    if (skip) {
      this.debug("AnimationManager - skipping animation");
    }
    return new Animation(__spreadProps(__spreadValues({}, opts), {
      id,
      skip,
      autoplay: this.isPlaying ? opts.autoplay : false,
      duration: (_b2 = opts.duration) != null ? _b2 : this.defaultDuration,
      onPlay: (controller) => {
        var _a3;
        batch.controllers.set(id, controller);
        this.requestAnimation();
        if (disableInteractions) {
          this.interactionManager.pause("animation");
        }
        (_a3 = opts.onPlay) == null ? void 0 : _a3.call(controller, controller);
      },
      onStop: (controller) => {
        var _a3;
        batch.controllers.delete(id);
        if (disableInteractions) {
          this.interactionManager.resume("animation");
        }
        (_a3 = opts.onStop) == null ? void 0 : _a3.call(controller, controller);
      }
    }));
  }
  play() {
    if (this.isPlaying) {
      return;
    }
    this.isPlaying = true;
    this.debug("AnimationManager.play()");
    for (const controller of this.batch.controllers.values()) {
      try {
        controller.play();
      } catch (error) {
        this.failsafeOnError(error);
      }
    }
    this.requestAnimation();
  }
  pause() {
    if (!this.isPlaying) {
      return;
    }
    this.isPlaying = false;
    this.cancelAnimation();
    this.debug("AnimationManager.pause()");
    for (const controller of this.batch.controllers.values()) {
      try {
        controller.pause();
      } catch (error) {
        this.failsafeOnError(error);
      }
    }
  }
  stop() {
    this.isPlaying = false;
    this.cancelAnimation();
    this.debug("AnimationManager.stop()");
    for (const controller of this.batch.controllers.values()) {
      try {
        controller.stop();
      } catch (error) {
        this.failsafeOnError(error, false);
      }
    }
  }
  stopByAnimationId(id) {
    var _a;
    try {
      if (id != null && this.batch.controllers.has(id)) {
        (_a = this.batch.controllers.get(id)) == null ? void 0 : _a.stop();
      }
    } catch (error) {
      this.failsafeOnError(error);
      return;
    }
  }
  stopByAnimationGroupId(id) {
    for (const controller of this.batch.controllers.values()) {
      if (controller.groupId === id) {
        this.stopByAnimationId(controller.id);
      }
    }
  }
  reset() {
    if (this.isPlaying) {
      this.stop();
      this.play();
    } else {
      this.stop();
    }
  }
  skip(skip = true) {
    this.skipAnimations = skip;
  }
  isSkipped() {
    return this.skipAnimations || this.batch.isSkipped();
  }
  isActive() {
    return this.isPlaying && this.batch.isActive();
  }
  skipCurrentBatch() {
    if (Debug.check(...DEBUG_SELECTORS)) {
      this.debug(`AnimationManager - skipCurrentBatch()`, { stack: new Error().stack });
    }
    this.batch.skip();
  }
  /** Mocking point for tests to guarantee that animation updates happen. */
  isSkippingFrames() {
    return true;
  }
  /** Mocking point for tests to capture requestAnimationFrame callbacks. */
  scheduleAnimationFrame(cb) {
    this.requestId = requestAnimationFrame(cb);
  }
  requestAnimation() {
    if (!this.batch.isActive() || this.requestId !== null)
      return;
    let prevTime;
    const onAnimationFrame = (time) => __async(this, null, function* () {
      const executeAnimationFrame = () => __async(this, null, function* () {
        const deltaTime = time - (prevTime != null ? prevTime : time);
        prevTime = time;
        this.debug("AnimationManager - onAnimationFrame()", {
          controllersCount: this.batch.controllers.size
        });
        for (const controller of this.batch.controllers.values()) {
          try {
            controller.update(deltaTime);
          } catch (error) {
            this.failsafeOnError(error);
          }
        }
        this.listeners.dispatch("animation-frame", {
          type: "animation-frame",
          deltaMs: deltaTime
        });
      });
      if (this.isSkippingFrames()) {
        yield this.chartUpdateMutex.acquireImmediately(executeAnimationFrame);
      } else {
        yield this.chartUpdateMutex.acquire(executeAnimationFrame);
      }
      if (this.batch.isActive()) {
        this.scheduleAnimationFrame(onAnimationFrame);
      }
    });
    this.scheduleAnimationFrame(onAnimationFrame);
  }
  cancelAnimation() {
    if (this.requestId === null)
      return;
    cancelAnimationFrame(this.requestId);
    this.requestId = null;
    this.startBatch();
  }
  failsafeOnError(error, cancelAnimation = true) {
    Logger.error("Error during animation, skipping animations", error);
    if (cancelAnimation) {
      this.cancelAnimation();
    }
  }
  startBatch(skipAnimations) {
    this.debug(`AnimationManager - startBatch() with skipAnimations=${skipAnimations}.`);
    this.reset();
    this.batch.destroy();
    this.batch = new AnimationBatch();
    if (skipAnimations === true) {
      this.batch.skip();
    }
  }
  endBatch() {
    this.debug(
      `AnimationManager - endBatch() with ${this.batch.controllers.size} animations; skipped: ${this.batch.isSkipped()}.`
    );
    if (this.batch.isSkipped() && !this.batch.isActive()) {
      this.batch.skip(false);
    }
  }
};
var AnimationBatch = class {
  constructor() {
    this.controllers = /* @__PURE__ */ new Map();
    this.skipAnimations = false;
  }
  // private phase?: 'initial-load' | 'remove' | 'update' | 'add';
  isActive() {
    return this.controllers.size > 0;
  }
  skip(skip = true) {
    if (this.skipAnimations === false && skip === true) {
      for (const controller of this.controllers.values()) {
        controller.stop();
      }
      this.controllers.clear();
    }
    this.skipAnimations = skip;
  }
  isSkipped() {
    return this.skipAnimations;
  }
  destroy() {
  }
};
var ChartEventManager = class extends BaseManager {
  legendItemClick(series, itemId, enabled, legendItemName) {
    const event = {
      type: "legend-item-click",
      series,
      itemId,
      enabled,
      legendItemName
    };
    this.listeners.dispatch("legend-item-click", event);
  }
  legendItemDoubleClick(series, itemId, enabled, numVisibleItems, legendItemName) {
    const event = {
      type: "legend-item-double-click",
      series,
      itemId,
      enabled,
      legendItemName,
      numVisibleItems
    };
    this.listeners.dispatch("legend-item-double-click", event);
  }
  axisHover(axisId, direction) {
    const event = {
      type: "axis-hover",
      axisId,
      direction
    };
    this.listeners.dispatch("axis-hover", event);
  }
};
var CursorManager = class {
  constructor(element2) {
    this.states = {};
    this.element = element2;
  }
  updateCursor(callerId, style) {
    delete this.states[callerId];
    if (style != null) {
      this.states[callerId] = { style };
    }
    this.applyStates();
  }
  applyStates() {
    let styleToApply = "default";
    Object.entries(this.states).reverse().slice(0, 1).forEach(([_, { style }]) => styleToApply = style);
    this.element.style.cursor = styleToApply;
  }
  getCursor() {
    return this.element.style.cursor;
  }
};
var HighlightManager = class extends BaseManager {
  constructor() {
    super(...arguments);
    this.highlightStates = /* @__PURE__ */ new Map();
    this.pickedStates = /* @__PURE__ */ new Map();
  }
  updateHighlight(callerId, highlightedDatum) {
    this.highlightStates.delete(callerId);
    if (highlightedDatum != null) {
      this.highlightStates.set(callerId, highlightedDatum);
    }
    this.applyHighlightStates();
  }
  getActiveHighlight() {
    return this.activeHighlight;
  }
  updatePicked(callerId, clickableDatum) {
    this.pickedStates.delete(callerId);
    if (clickableDatum != null) {
      this.pickedStates.set(callerId, clickableDatum);
    }
    this.applyPickedStates();
  }
  getActivePicked() {
    return this.activePicked;
  }
  applyHighlightStates() {
    const { activeHighlight: previousHighlight } = this;
    this.activeHighlight = Array.from(this.highlightStates.values()).pop();
    if (!this.isEqual(this.activeHighlight, previousHighlight)) {
      this.listeners.dispatch("highlight-change", {
        type: "highlight-change",
        currentHighlight: this.activeHighlight,
        previousHighlight
      });
    }
  }
  applyPickedStates() {
    this.activePicked = Array.from(this.pickedStates.values()).pop();
  }
  isEqual(a, b) {
    return a === b || (a == null ? void 0 : a.series) === (b == null ? void 0 : b.series) && (a == null ? void 0 : a.itemId) === (b == null ? void 0 : b.itemId) && (a == null ? void 0 : a.datum) === (b == null ? void 0 : b.datum);
  }
};
var WINDOW_EVENT_HANDLERS = ["pagehide", "mousemove", "mouseup"];
var EVENT_HANDLERS = [
  "click",
  "dblclick",
  "contextmenu",
  "mousedown",
  "mouseout",
  "mouseenter",
  "touchstart",
  "touchmove",
  "touchend",
  "touchcancel",
  "wheel"
];
var CSS = `
.ag-chart-wrapper {
    touch-action: none;
}
`;
var _InteractionManager = class _InteractionManager2 extends BaseManager {
  constructor(element2, document2, window2) {
    super();
    this.eventHandler = (event) => this.processEvent(event);
    this.mouseDown = false;
    this.touchDown = false;
    this.pausers = { animation: 0, "context-menu": 0 };
    this.rootElement = document2.body;
    this.element = element2;
    this.window = window2;
    for (const type of EVENT_HANDLERS) {
      if (type.startsWith("touch")) {
        element2.addEventListener(type, this.eventHandler, { passive: true });
      } else if (type === "wheel") {
        element2.addEventListener(type, this.eventHandler, { passive: false });
      } else {
        element2.addEventListener(type, this.eventHandler);
      }
    }
    for (const type of WINDOW_EVENT_HANDLERS) {
      this.window.addEventListener(type, this.eventHandler);
    }
    if (!_InteractionManager2.interactionDocuments.includes(document2)) {
      injectStyle(document2, CSS);
      _InteractionManager2.interactionDocuments.push(document2);
    }
  }
  destroy() {
    for (const type of WINDOW_EVENT_HANDLERS) {
      this.window.removeEventListener(type, this.eventHandler);
    }
    for (const type of EVENT_HANDLERS) {
      this.element.removeEventListener(type, this.eventHandler);
    }
  }
  resume(pauseType) {
    this.pausers[pauseType]--;
  }
  pause(pauseType) {
    this.pausers[pauseType]++;
  }
  processEvent(event) {
    const types = this.decideInteractionEventTypes(event);
    if (types.length > 0) {
      this.dispatchEvent(event, types).catch((e) => Logger.errorOnce(e));
    }
  }
  dispatchEvent(event, types) {
    return __async(this, null, function* () {
      const coords = this.calculateCoordinates(event);
      if (coords == null) {
        return;
      }
      const pauses = Object.entries(this.pausers).filter(([, count2]) => count2 > 0).map(([pause]) => pause);
      for (const type of types) {
        this.listeners.dispatchWrapHandlers(
          type,
          (handler, meta, interactionEvent) => {
            var _a;
            if (pauses.length > 0 && !((_a = meta == null ? void 0 : meta.bypassPause) == null ? void 0 : _a.some((p) => pauses.includes(p)))) {
              return;
            }
            if (!interactionEvent.consumed) {
              handler(interactionEvent);
            }
          },
          this.buildEvent(__spreadValues({ type, event, pauses }, coords))
        );
      }
    });
  }
  decideInteractionEventTypes(event) {
    const dragStart = "drag-start";
    switch (event.type) {
      case "click":
        return ["click"];
      case "dblclick":
        return ["dblclick"];
      case "contextmenu":
        return ["contextmenu"];
      case "mousedown":
        this.mouseDown = true;
        this.dragStartElement = event.target;
        return [dragStart];
      case "touchstart":
        this.touchDown = true;
        this.dragStartElement = event.target;
        return [dragStart];
      case "touchmove":
      case "mousemove":
        if (!this.mouseDown && !this.touchDown && !this.isEventOverElement(event)) {
          return [];
        }
        return this.mouseDown || this.touchDown ? ["drag"] : ["hover"];
      case "mouseup":
        if (!this.mouseDown && !this.isEventOverElement(event)) {
          return [];
        }
        this.mouseDown = false;
        this.dragStartElement = void 0;
        return ["drag-end"];
      case "touchend":
        if (!this.touchDown && !this.isEventOverElement(event)) {
          return [];
        }
        this.touchDown = false;
        this.dragStartElement = void 0;
        return ["drag-end"];
      case "mouseout":
      case "touchcancel":
        return ["leave"];
      case "mouseenter":
        const mouseButtonDown = event instanceof MouseEvent && (event.buttons & 1) === 1;
        if (this.mouseDown !== mouseButtonDown) {
          this.mouseDown = mouseButtonDown;
          return [mouseButtonDown ? dragStart : "drag-end"];
        }
        return [];
      case "pagehide":
        return ["page-left"];
      case "wheel":
        return ["wheel"];
    }
    return [];
  }
  isEventOverElement(event) {
    var _a;
    return event.target === this.element || ((_a = event.target) == null ? void 0 : _a.parentElement) === this.element;
  }
  calculateCoordinates(event) {
    var _a;
    if (event instanceof MouseEvent) {
      const { clientX, clientY, pageX, pageY, offsetX, offsetY } = event;
      return this.fixOffsets(event, { clientX, clientY, pageX, pageY, offsetX, offsetY });
    } else if (typeof TouchEvent !== "undefined" && event instanceof TouchEvent) {
      const lastTouch = (_a = event.touches[0]) != null ? _a : event.changedTouches[0];
      const { clientX, clientY, pageX, pageY } = lastTouch;
      return __spreadProps(__spreadValues({}, _InteractionManager2.NULL_COORDS), { clientX, clientY, pageX, pageY });
    } else if (event instanceof PageTransitionEvent) {
      if (event.persisted) {
        return;
      }
      return _InteractionManager2.NULL_COORDS;
    }
  }
  fixOffsets(event, coords) {
    const offsets = (el) => {
      let x = 0;
      let y = 0;
      while (el) {
        x += el.offsetLeft;
        y += el.offsetTop;
        el = el.offsetParent;
      }
      return { x, y };
    };
    if (this.dragStartElement != null && event.target !== this.dragStartElement) {
      const offsetDragStart = offsets(this.dragStartElement);
      const offsetEvent = offsets(event.target);
      coords.offsetX -= offsetDragStart.x - offsetEvent.x;
      coords.offsetY -= offsetDragStart.y - offsetEvent.y;
    }
    return coords;
  }
  buildEvent(opts) {
    const { type, event, clientX, clientY, pauses } = opts;
    let { offsetX, offsetY, pageX, pageY } = opts;
    if (!isNumber2(offsetX) || !isNumber2(offsetY)) {
      const rect = this.element.getBoundingClientRect();
      offsetX = clientX - rect.left;
      offsetY = clientY - rect.top;
    }
    if (!isNumber2(pageX) || !isNumber2(pageY)) {
      const pageRect = this.rootElement.getBoundingClientRect();
      pageX = clientX - pageRect.left;
      pageY = clientY - pageRect.top;
    }
    const builtEvent = {
      type,
      offsetX,
      offsetY,
      pageX,
      pageY,
      sourceEvent: event,
      consumed: false,
      pauses,
      consume() {
        builtEvent.consumed = true;
      }
    };
    return builtEvent;
  }
};
_InteractionManager.interactionDocuments = [];
_InteractionManager.NULL_COORDS = {
  clientX: -Infinity,
  clientY: -Infinity,
  pageX: -Infinity,
  pageY: -Infinity,
  offsetX: -Infinity,
  offsetY: -Infinity
};
var InteractionManager = _InteractionManager;
var TooltipManager = class {
  constructor(tooltip, interactionManager) {
    this.states = {};
    this.exclusiveAreas = {};
    this.destroyFns = [];
    this.tooltip = tooltip;
    this.destroyFns.push(interactionManager.addListener("hover", (e) => this.checkExclusiveRects(e)));
  }
  getRange() {
    return this.tooltip.range;
  }
  updateTooltip(callerId, meta, content) {
    var _a;
    if (content == null) {
      content = (_a = this.states[callerId]) == null ? void 0 : _a.content;
    }
    this.states[callerId] = { content, meta };
    this.applyStates();
  }
  updateExclusiveRect(callerId, area2) {
    if (area2) {
      this.exclusiveAreas[callerId] = area2;
    } else {
      delete this.exclusiveAreas[callerId];
    }
  }
  removeTooltip(callerId) {
    delete this.states[callerId];
    this.applyStates();
  }
  getTooltipMeta(callerId) {
    var _a;
    return (_a = this.states[callerId]) == null ? void 0 : _a.meta;
  }
  destroy() {
    for (const destroyFn of this.destroyFns) {
      destroyFn();
    }
  }
  checkExclusiveRects(e) {
    let newAppliedExclusiveArea;
    for (const [entryId, area2] of Object.entries(this.exclusiveAreas)) {
      if (!area2.containsPoint(e.offsetX, e.offsetY)) {
        continue;
      }
      newAppliedExclusiveArea = entryId;
      break;
    }
    if (newAppliedExclusiveArea === this.appliedExclusiveArea) {
      return;
    }
    this.appliedExclusiveArea = newAppliedExclusiveArea;
    this.applyStates();
  }
  applyStates() {
    var _a;
    const ids = this.appliedExclusiveArea ? [this.appliedExclusiveArea] : Object.keys(this.states);
    let contentToApply;
    let metaToApply;
    ids.reverse();
    ids.slice(0, 1).forEach((id) => {
      var _a2;
      const { content, meta } = (_a2 = this.states[id]) != null ? _a2 : {};
      contentToApply = content;
      metaToApply = meta;
    });
    if (metaToApply === void 0 || contentToApply === void 0) {
      this.appliedState = void 0;
      this.tooltip.toggle(false);
      return;
    }
    if (((_a = this.appliedState) == null ? void 0 : _a.content) === contentToApply) {
      const renderInstantly = this.tooltip.isVisible();
      this.tooltip.show(metaToApply, void 0, renderInstantly);
    } else {
      this.tooltip.show(metaToApply, contentToApply);
    }
    this.appliedState = { content: contentToApply, meta: metaToApply };
  }
  static makeTooltipMeta(event, canvas, datum, window2) {
    var _a, _b, _c, _d;
    const { pageX, pageY, offsetX, offsetY } = event;
    const { tooltip } = datum.series.properties;
    const position = {
      xOffset: tooltip.position.xOffset,
      yOffset: tooltip.position.yOffset
    };
    const meta = {
      pageX,
      pageY,
      offsetX,
      offsetY,
      event,
      showArrow: tooltip.showArrow,
      position
    };
    const refPoint = (_b = (_a = datum.yBar) == null ? void 0 : _a.upperPoint) != null ? _b : datum.midPoint;
    if (tooltip.position.type === "node" && refPoint) {
      const { x, y } = refPoint;
      const point = datum.series.contentGroup.inverseTransformPoint(x, y);
      const canvasRect = canvas.element.getBoundingClientRect();
      return __spreadProps(__spreadValues({}, meta), {
        pageX: Math.round(canvasRect.left + window2.scrollX + point.x),
        pageY: Math.round(canvasRect.top + window2.scrollY + point.y),
        offsetX: Math.round(point.x),
        offsetY: Math.round(point.y)
      });
    }
    meta.enableInteraction = (_d = (_c = tooltip.interaction) == null ? void 0 : _c.enabled) != null ? _d : false;
    return meta;
  }
};
var ZoomManager = class extends BaseManager {
  constructor() {
    super(...arguments);
    this.axes = {};
  }
  updateAxes(axes) {
    var _a;
    const removedAxes = new Set(Object.keys(this.axes));
    axes.forEach((axis) => {
      var _a2, _b, _c;
      removedAxes.delete(axis.id);
      (_c = (_a2 = this.axes)[_b = axis.id]) != null ? _c : _a2[_b] = new AxisZoomManager(axis);
    });
    removedAxes.forEach((axisId) => {
      delete this.axes[axisId];
    });
    if ((_a = this.initialZoom) == null ? void 0 : _a.newZoom) {
      this.updateZoom(this.initialZoom.callerId, this.initialZoom.newZoom);
    }
    this.initialZoom = void 0;
  }
  updateZoom(callerId, newZoom) {
    if (Object.keys(this.axes).length === 0) {
      this.initialZoom = { callerId, newZoom };
      return;
    }
    Object.values(this.axes).forEach((axis) => {
      axis.updateZoom(callerId, newZoom == null ? void 0 : newZoom[axis.getDirection()]);
    });
    this.applyStates();
  }
  updateAxisZoom(callerId, axisId, newZoom) {
    var _a;
    (_a = this.axes[axisId]) == null ? void 0 : _a.updateZoom(callerId, newZoom);
    this.applyStates();
  }
  getZoom() {
    let x;
    let y;
    Object.values(this.axes).forEach((axis) => {
      if (axis.getDirection() === "x") {
        x = axis.getZoom();
      } else if (axis.getDirection() === "y") {
        y = axis.getZoom();
      }
    });
    if (x || y) {
      return { x, y };
    }
  }
  getAxisZoom(axisId) {
    var _a;
    return (_a = this.axes[axisId]) == null ? void 0 : _a.getZoom();
  }
  getAxisZooms() {
    const axes = {};
    for (const [axisId, axis] of Object.entries(this.axes)) {
      axes[axisId] = {
        direction: axis.getDirection(),
        zoom: axis.getZoom()
      };
    }
    return axes;
  }
  applyStates() {
    const changed = Object.values(this.axes).map((axis) => axis.applyStates()).some(Boolean);
    if (!changed) {
      return;
    }
    const currentZoom = this.getZoom();
    const axes = {};
    for (const [axisId, axis] of Object.entries(this.axes)) {
      axes[axisId] = axis.getZoom();
    }
    this.listeners.dispatch("zoom-change", __spreadProps(__spreadValues({
      type: "zoom-change"
    }, currentZoom != null ? currentZoom : {}), {
      axes
    }));
  }
};
var AxisZoomManager = class {
  constructor(axis) {
    this.states = {};
    this.axis = axis;
    const [min = 0, max = 1] = axis.visibleRange;
    this.currentZoom = { min, max };
    this.states["__initial__"] = this.currentZoom;
  }
  getDirection() {
    return this.axis.direction;
  }
  updateZoom(callerId, newZoom) {
    delete this.states[callerId];
    if (newZoom != null) {
      this.states[callerId] = __spreadValues({}, newZoom);
    }
  }
  getZoom() {
    return this.currentZoom;
  }
  applyStates() {
    var _a, _b;
    const prevZoom = this.currentZoom;
    const last = Object.keys(this.states)[Object.keys(this.states).length - 1];
    this.currentZoom = __spreadValues({}, this.states[last]);
    return (prevZoom == null ? void 0 : prevZoom.min) !== ((_a = this.currentZoom) == null ? void 0 : _a.min) || (prevZoom == null ? void 0 : prevZoom.max) !== ((_b = this.currentZoom) == null ? void 0 : _b.max);
  }
};
var LayoutService = class extends Listeners {
  constructor() {
    super(...arguments);
    this.layoutComplete = "layout-complete";
  }
  addListener(eventType, handler) {
    if (this.isLayoutStage(eventType) || this.isLayoutComplete(eventType)) {
      return super.addListener(eventType, handler);
    }
    throw new Error(`AG Charts - unsupported listener type: ${eventType}`);
  }
  dispatchPerformLayout(stage, ctx) {
    if (this.isLayoutStage(stage)) {
      return this.getListenersByType(stage).reduce((result, listener) => {
        try {
          return listener.handler(result);
        } catch (e) {
          Logger.errorOnce(e);
          return result;
        }
      }, ctx);
    }
    return ctx;
  }
  dispatchLayoutComplete(event) {
    this.dispatch(this.layoutComplete, event);
  }
  isLayoutStage(eventType) {
    return eventType !== this.layoutComplete;
  }
  isLayoutComplete(eventType) {
    return eventType === this.layoutComplete;
  }
};
function gridLayout({
  orientation,
  bboxes,
  maxHeight,
  maxWidth,
  itemPaddingY = 0,
  itemPaddingX = 0,
  forceResult = false
}) {
  const horizontal = orientation === "horizontal";
  const primary = {
    max: horizontal ? maxWidth : maxHeight,
    fn: horizontal ? (b) => b.width : (b) => b.height,
    padding: horizontal ? itemPaddingX : itemPaddingY
  };
  const secondary = {
    max: !horizontal ? maxWidth : maxHeight,
    fn: !horizontal ? (b) => b.width : (b) => b.height,
    padding: !horizontal ? itemPaddingX : itemPaddingY
  };
  let processedBBoxCount = 0;
  const rawPages = [];
  while (processedBBoxCount < bboxes.length) {
    const unprocessedBBoxes = bboxes.slice(processedBBoxCount);
    const result = processBBoxes(unprocessedBBoxes, processedBBoxCount, primary, secondary, forceResult);
    if (!result) {
      return;
    }
    processedBBoxCount += result.processedBBoxCount;
    rawPages.push(result.pageIndices);
  }
  return buildPages(rawPages, orientation, bboxes, itemPaddingY, itemPaddingX);
}
function processBBoxes(bboxes, indexOffset, primary, secondary, forceResult) {
  const minGuess = 1;
  let startingGuess = estimateStartingGuess(bboxes, primary);
  if (startingGuess < minGuess) {
    if (!forceResult) {
      return void 0;
    }
    startingGuess = minGuess;
  }
  for (let guess = startingGuess; guess >= minGuess; guess--) {
    const pageIndices = calculatePage(bboxes, indexOffset, guess, primary, secondary, forceResult);
    if (pageIndices == null && guess <= minGuess) {
      return void 0;
    }
    if (pageIndices == null) {
      continue;
    }
    if (typeof pageIndices === "number") {
      if (pageIndices <= minGuess) {
        return void 0;
      }
      guess = pageIndices < guess && pageIndices > minGuess ? pageIndices : guess;
      continue;
    }
    const processedBBoxCount = pageIndices.length * pageIndices[0].length;
    return { processedBBoxCount, pageIndices };
  }
}
function calculatePage(bboxes, indexOffset, primaryCount, primary, secondary, forceResult) {
  var _a;
  const result = [];
  let sumSecondary = 0;
  let currentMaxSecondary = 0;
  let currentPrimaryIndices = [];
  const maxPrimaryValues = [];
  for (let bboxIndex = 0; bboxIndex < bboxes.length; bboxIndex++) {
    const primaryValueIdx = (bboxIndex + primaryCount) % primaryCount;
    if (primaryValueIdx === 0) {
      sumSecondary += currentMaxSecondary;
      currentMaxSecondary = 0;
      if (currentPrimaryIndices.length > 0) {
        result.push(currentPrimaryIndices);
      }
      currentPrimaryIndices = [];
    }
    const primaryValue = primary.fn(bboxes[bboxIndex]) + primary.padding;
    maxPrimaryValues[primaryValueIdx] = Math.max((_a = maxPrimaryValues[primaryValueIdx]) != null ? _a : 0, primaryValue);
    currentMaxSecondary = Math.max(currentMaxSecondary, secondary.fn(bboxes[bboxIndex]) + secondary.padding);
    const currentSecondaryDimension = sumSecondary + currentMaxSecondary;
    const returnResult = !forceResult || result.length > 0;
    if (currentSecondaryDimension > secondary.max && returnResult) {
      currentPrimaryIndices = [];
      break;
    }
    const sumPrimary = maxPrimaryValues.reduce((sum2, next) => sum2 + next, 0);
    if (sumPrimary > primary.max && !forceResult) {
      if (maxPrimaryValues.length < primaryCount) {
        return maxPrimaryValues.length;
      }
      return void 0;
    }
    currentPrimaryIndices.push(bboxIndex + indexOffset);
  }
  if (currentPrimaryIndices.length > 0) {
    result.push(currentPrimaryIndices);
  }
  return result.length > 0 ? result : void 0;
}
function buildPages(rawPages, orientation, bboxes, itemPaddingY, itemPaddingX) {
  let maxPageWidth = 0;
  let maxPageHeight = 0;
  const pages = rawPages.map((indices) => {
    if (orientation === "horizontal") {
      indices = transpose(indices);
    }
    let endIndex = 0;
    const columns = indices.map((colIndices) => {
      const colBBoxes = colIndices.map((bboxIndex) => {
        endIndex = Math.max(bboxIndex, endIndex);
        return bboxes[bboxIndex];
      });
      let columnHeight = 0;
      let columnWidth = 0;
      colBBoxes.forEach((bbox) => {
        columnHeight += bbox.height + itemPaddingY;
        columnWidth = Math.max(columnWidth, bbox.width + itemPaddingX);
      });
      return {
        indices: colIndices,
        bboxes: colBBoxes,
        columnHeight: Math.ceil(columnHeight),
        columnWidth: Math.ceil(columnWidth)
      };
    });
    let pageWidth = 0;
    let pageHeight = 0;
    columns.forEach((column) => {
      pageWidth += column.columnWidth;
      pageHeight = Math.max(pageHeight, column.columnHeight);
    });
    maxPageWidth = Math.max(pageWidth, maxPageWidth);
    maxPageHeight = Math.max(pageHeight, maxPageHeight);
    return {
      columns,
      startIndex: indices[0][0],
      endIndex,
      pageWidth,
      pageHeight
    };
  });
  return { pages, maxPageWidth, maxPageHeight };
}
function transpose(data) {
  const result = [];
  for (const _ of data[0]) {
    result.push([]);
  }
  data.forEach((innerData, dataIdx) => {
    innerData.forEach((item, itemIdx) => {
      result[itemIdx][dataIdx] = item;
    });
  });
  return result;
}
function estimateStartingGuess(bboxes, primary) {
  const n = bboxes.length;
  let primarySum = 0;
  for (let bboxIndex = 0; bboxIndex < n; bboxIndex++) {
    primarySum += primary.fn(bboxes[bboxIndex]) + primary.padding;
    if (primarySum > primary.max) {
      const ratio = n / bboxIndex;
      if (ratio < 2) {
        return Math.ceil(n / 2);
      }
      return bboxIndex;
    }
  }
  return n;
}
var MarkerLabel = class extends Group {
  constructor() {
    super({ name: "markerLabelGroup" });
    this.label = new Text();
    this.line = new Line();
    this._marker = new Square();
    this._markerSize = 15;
    this._spacing = 8;
    const { marker, label, line } = this;
    label.textBaseline = "middle";
    label.fontSize = 12;
    label.fontFamily = "Verdana, sans-serif";
    label.fill = "black";
    label.y = HdpiCanvas.has.textMetrics ? 1 : 0;
    this.append([line, marker, label]);
    this.update();
  }
  set marker(value) {
    if (this._marker !== value) {
      this.removeChild(this._marker);
      this._marker = value;
      this.appendChild(value);
      this.update();
    }
  }
  get marker() {
    return this._marker;
  }
  set markerSize(value) {
    if (this._markerSize !== value) {
      this._markerSize = value;
      this.update();
    }
  }
  get markerSize() {
    return this._markerSize;
  }
  set spacing(value) {
    if (this._spacing !== value) {
      this._spacing = value;
      this.update();
    }
  }
  get spacing() {
    return this._spacing;
  }
  setSeriesStrokeOffset(xOff) {
    const offset4 = this.marker.size / 2 + xOff;
    this.line.x1 = -offset4;
    this.line.x2 = offset4;
    this.line.y1 = 0;
    this.line.y2 = 0;
    this.line.markDirtyTransform();
    this.update();
  }
  update() {
    this.marker.size = this.markerSize;
    const lineEnd = this.line.visible ? this.line.x2 : -Infinity;
    const markerEnd = this.markerSize / 2;
    this.label.x = Math.max(lineEnd, markerEnd) + this.spacing;
  }
  render(renderCtx) {
    this.marker.opacity = this.opacity;
    this.label.opacity = this.opacity;
    this.line.opacity = this.opacity;
    super.render(renderCtx);
  }
};
MarkerLabel.className = "MarkerLabel";
__decorateClass([
  ProxyPropertyOnWrite("label")
], MarkerLabel.prototype, "text", 2);
__decorateClass([
  ProxyPropertyOnWrite("label")
], MarkerLabel.prototype, "fontStyle", 2);
__decorateClass([
  ProxyPropertyOnWrite("label")
], MarkerLabel.prototype, "fontWeight", 2);
__decorateClass([
  ProxyPropertyOnWrite("label")
], MarkerLabel.prototype, "fontSize", 2);
__decorateClass([
  ProxyPropertyOnWrite("label")
], MarkerLabel.prototype, "fontFamily", 2);
__decorateClass([
  ProxyPropertyOnWrite("label", "fill")
], MarkerLabel.prototype, "color", 2);
__decorateClass([
  ProxyPropertyOnWrite("marker", "fill")
], MarkerLabel.prototype, "markerFill", 2);
__decorateClass([
  ProxyPropertyOnWrite("marker", "stroke")
], MarkerLabel.prototype, "markerStroke", 2);
__decorateClass([
  ProxyPropertyOnWrite("marker", "strokeWidth")
], MarkerLabel.prototype, "markerStrokeWidth", 2);
__decorateClass([
  ProxyPropertyOnWrite("marker", "fillOpacity")
], MarkerLabel.prototype, "markerFillOpacity", 2);
__decorateClass([
  ProxyPropertyOnWrite("marker", "strokeOpacity")
], MarkerLabel.prototype, "markerStrokeOpacity", 2);
__decorateClass([
  ProxyPropertyOnWrite("marker", "visible")
], MarkerLabel.prototype, "markerVisible", 2);
__decorateClass([
  ProxyPropertyOnWrite("line", "stroke")
], MarkerLabel.prototype, "lineStroke", 2);
__decorateClass([
  ProxyPropertyOnWrite("line", "strokeWidth")
], MarkerLabel.prototype, "lineStrokeWidth", 2);
__decorateClass([
  ProxyPropertyOnWrite("line", "strokeOpacity")
], MarkerLabel.prototype, "lineStrokeOpacity", 2);
__decorateClass([
  ProxyPropertyOnWrite("line", "lineDash")
], MarkerLabel.prototype, "lineLineDash", 2);
__decorateClass([
  ProxyPropertyOnWrite("line", "visible")
], MarkerLabel.prototype, "lineVisible", 2);
var PaginationLabel = class {
  constructor() {
    this.color = "black";
    this.fontStyle = void 0;
    this.fontWeight = void 0;
    this.fontSize = 12;
    this.fontFamily = "Verdana, sans-serif";
  }
};
__decorateClass([
  Validate(COLOR_STRING)
], PaginationLabel.prototype, "color", 2);
__decorateClass([
  Validate(FONT_STYLE, { optional: true })
], PaginationLabel.prototype, "fontStyle", 2);
__decorateClass([
  Validate(FONT_WEIGHT, { optional: true })
], PaginationLabel.prototype, "fontWeight", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PaginationLabel.prototype, "fontSize", 2);
__decorateClass([
  Validate(STRING)
], PaginationLabel.prototype, "fontFamily", 2);
var PaginationMarkerStyle = class {
  constructor() {
    this.size = 15;
    this.fill = void 0;
    this.fillOpacity = void 0;
    this.stroke = void 0;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PaginationMarkerStyle.prototype, "size", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], PaginationMarkerStyle.prototype, "fill", 2);
__decorateClass([
  Validate(RATIO, { optional: true })
], PaginationMarkerStyle.prototype, "fillOpacity", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], PaginationMarkerStyle.prototype, "stroke", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PaginationMarkerStyle.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO)
], PaginationMarkerStyle.prototype, "strokeOpacity", 2);
var PaginationMarker = class {
  constructor(parent) {
    this.parent = parent;
    this.shape = Triangle;
    this.size = 15;
    this.padding = 8;
  }
};
__decorateClass([
  ActionOnSet({
    changeValue() {
      if (this.parent.marker === this) {
        this.parent.onMarkerShapeChange();
      }
    }
  })
], PaginationMarker.prototype, "shape", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PaginationMarker.prototype, "size", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PaginationMarker.prototype, "padding", 2);
var Pagination = class {
  constructor(chartUpdateCallback, pageUpdateCallback, interactionManager, cursorManager) {
    this.chartUpdateCallback = chartUpdateCallback;
    this.pageUpdateCallback = pageUpdateCallback;
    this.interactionManager = interactionManager;
    this.cursorManager = cursorManager;
    this.id = createId(this);
    this.group = new Group({ name: "pagination" });
    this.labelNode = new Text();
    this.marker = new PaginationMarker(this);
    this.activeStyle = new PaginationMarkerStyle();
    this.inactiveStyle = new PaginationMarkerStyle();
    this.highlightStyle = new PaginationMarkerStyle();
    this.label = new PaginationLabel();
    this.totalPages = 0;
    this.currentPage = 0;
    this.translationX = 0;
    this.translationY = 0;
    this.nextButtonDisabled = false;
    this.previousButtonDisabled = false;
    this._visible = true;
    this._enabled = true;
    this._orientation = "vertical";
    this._nextButton = new Triangle();
    this._previousButton = new Triangle();
    const { labelNode } = this;
    labelNode.textBaseline = "middle";
    labelNode.fontSize = 12;
    labelNode.fontFamily = "Verdana, sans-serif";
    labelNode.fill = "black";
    labelNode.y = HdpiCanvas.has.textMetrics ? 1 : 0;
    this.group.append([this.nextButton, this.previousButton, labelNode]);
    this.interactionManager.addListener("click", (event) => this.onPaginationClick(event));
    this.interactionManager.addListener("hover", (event) => this.onPaginationMouseMove(event));
    this.update();
    this.updateMarkers();
  }
  set visible(value) {
    this._visible = value;
    this.updateGroupVisibility();
  }
  get visible() {
    return this._visible;
  }
  set enabled(value) {
    this._enabled = value;
    this.updateGroupVisibility();
  }
  get enabled() {
    return this._enabled;
  }
  updateGroupVisibility() {
    this.group.visible = this.enabled && this.visible;
  }
  set orientation(value) {
    this._orientation = value;
    switch (value) {
      case "horizontal": {
        this.previousButton.rotation = -Math.PI / 2;
        this.nextButton.rotation = Math.PI / 2;
        break;
      }
      case "vertical":
      default: {
        this.previousButton.rotation = 0;
        this.nextButton.rotation = Math.PI;
      }
    }
  }
  get orientation() {
    return this._orientation;
  }
  set nextButton(value) {
    if (this._nextButton !== value) {
      this.group.removeChild(this._nextButton);
      this._nextButton = value;
      this.group.appendChild(value);
    }
  }
  get nextButton() {
    return this._nextButton;
  }
  set previousButton(value) {
    if (this._previousButton !== value) {
      this.group.removeChild(this._previousButton);
      this._previousButton = value;
      this.group.appendChild(value);
    }
  }
  get previousButton() {
    return this._previousButton;
  }
  update() {
    this.updateLabel();
    this.updatePositions();
    this.enableOrDisableButtons();
  }
  updatePositions() {
    this.group.translationX = this.translationX;
    this.group.translationY = this.translationY;
    this.updateLabelPosition();
    this.updateNextButtonPosition();
  }
  updateLabelPosition() {
    const { size: markerSize, padding: markerPadding } = this.marker;
    this.nextButton.size = markerSize;
    this.previousButton.size = markerSize;
    this.labelNode.x = markerSize / 2 + markerPadding;
  }
  updateNextButtonPosition() {
    const labelBBox = this.labelNode.computeBBox();
    this.nextButton.translationX = labelBBox.x + labelBBox.width + this.marker.size / 2 + this.marker.padding;
  }
  updateLabel() {
    const {
      currentPage,
      totalPages: pages,
      labelNode,
      label: { color, fontStyle, fontWeight, fontSize, fontFamily }
    } = this;
    labelNode.text = `${currentPage + 1} / ${pages}`;
    labelNode.fill = color;
    labelNode.fontStyle = fontStyle;
    labelNode.fontWeight = fontWeight;
    labelNode.fontSize = fontSize;
    labelNode.fontFamily = fontFamily;
  }
  updateMarkers() {
    const {
      nextButton,
      previousButton,
      nextButtonDisabled,
      previousButtonDisabled,
      activeStyle,
      inactiveStyle,
      highlightStyle,
      highlightActive
    } = this;
    const buttonStyle = (button, disabled) => {
      if (disabled) {
        return inactiveStyle;
      } else if (button === highlightActive) {
        return highlightStyle;
      }
      return activeStyle;
    };
    this.updateMarker(nextButton, buttonStyle("next", nextButtonDisabled));
    this.updateMarker(previousButton, buttonStyle("previous", previousButtonDisabled));
  }
  updateMarker(marker, style) {
    var _a;
    const { size } = this.marker;
    marker.size = size;
    marker.fill = style.fill;
    marker.fillOpacity = (_a = style.fillOpacity) != null ? _a : 1;
    marker.stroke = style.stroke;
    marker.strokeWidth = style.strokeWidth;
    marker.strokeOpacity = style.strokeOpacity;
  }
  enableOrDisableButtons() {
    const { currentPage, totalPages } = this;
    const zeroPagesToDisplay = totalPages === 0;
    const onLastPage = currentPage === totalPages - 1;
    const onFirstPage = currentPage === 0;
    this.nextButtonDisabled = onLastPage || zeroPagesToDisplay;
    this.previousButtonDisabled = onFirstPage || zeroPagesToDisplay;
  }
  nextButtonContainsPoint(offsetX, offsetY) {
    return !this.nextButtonDisabled && this.nextButton.containsPoint(offsetX, offsetY);
  }
  previousButtonContainsPoint(offsetX, offsetY) {
    return !this.previousButtonDisabled && this.previousButton.containsPoint(offsetX, offsetY);
  }
  onPaginationClick(event) {
    const { offsetX, offsetY } = event;
    if (this.nextButtonContainsPoint(offsetX, offsetY)) {
      this.incrementPage();
      this.onPaginationChanged();
      event.consume();
    } else if (this.previousButtonContainsPoint(offsetX, offsetY)) {
      this.decrementPage();
      this.onPaginationChanged();
      event.consume();
    }
  }
  onPaginationMouseMove(event) {
    const { offsetX, offsetY } = event;
    if (this.nextButtonContainsPoint(offsetX, offsetY)) {
      this.cursorManager.updateCursor(this.id, "pointer");
      this.highlightActive = "next";
    } else if (this.previousButtonContainsPoint(offsetX, offsetY)) {
      this.cursorManager.updateCursor(this.id, "pointer");
      this.highlightActive = "previous";
    } else {
      this.cursorManager.updateCursor(this.id);
      this.highlightActive = void 0;
    }
    this.updateMarkers();
    this.chartUpdateCallback(
      5
      /* SCENE_RENDER */
    );
  }
  onPaginationChanged() {
    this.pageUpdateCallback(this.currentPage);
  }
  incrementPage() {
    this.currentPage = Math.min(this.currentPage + 1, this.totalPages - 1);
  }
  decrementPage() {
    this.currentPage = Math.max(this.currentPage - 1, 0);
  }
  onMarkerShapeChange() {
    const Marker2 = getMarker(this.marker.shape || Triangle);
    this.previousButton = new Marker2();
    this.nextButton = new Marker2();
    this.updatePositions();
    this.updateMarkers();
    this.chartUpdateCallback(
      5
      /* SCENE_RENDER */
    );
  }
  attachPagination(node) {
    node.append(this.group);
  }
  computeBBox() {
    return this.group.computeBBox();
  }
};
Pagination.className = "Pagination";
var LegendLabel = class {
  constructor() {
    this.maxLength = void 0;
    this.color = "black";
    this.fontStyle = void 0;
    this.fontWeight = void 0;
    this.fontSize = 12;
    this.fontFamily = "Verdana, sans-serif";
    this.formatter = void 0;
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], LegendLabel.prototype, "maxLength", 2);
__decorateClass([
  Validate(COLOR_STRING)
], LegendLabel.prototype, "color", 2);
__decorateClass([
  Validate(FONT_STYLE, { optional: true })
], LegendLabel.prototype, "fontStyle", 2);
__decorateClass([
  Validate(FONT_WEIGHT, { optional: true })
], LegendLabel.prototype, "fontWeight", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], LegendLabel.prototype, "fontSize", 2);
__decorateClass([
  Validate(STRING)
], LegendLabel.prototype, "fontFamily", 2);
__decorateClass([
  Validate(FUNCTION, { optional: true })
], LegendLabel.prototype, "formatter", 2);
var LegendMarker = class {
  constructor() {
    this.size = 15;
    this._shape = void 0;
    this.padding = 8;
    this.strokeWidth = void 0;
    this.enabled = true;
  }
  set shape(value) {
    var _a;
    this._shape = value;
    (_a = this.parent) == null ? void 0 : _a.onMarkerShapeChange();
  }
  get shape() {
    return this._shape;
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER)
], LegendMarker.prototype, "size", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], LegendMarker.prototype, "padding", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], LegendMarker.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], LegendMarker.prototype, "enabled", 2);
var LegendLine = class {
  constructor() {
    this.strokeWidth = void 0;
    this.length = void 0;
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], LegendLine.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], LegendLine.prototype, "length", 2);
var LegendItem = class {
  constructor() {
    this.marker = new LegendMarker();
    this.label = new LegendLabel();
    this.line = new LegendLine();
    this.maxWidth = void 0;
    this.paddingX = 16;
    this.paddingY = 8;
    this.toggleSeriesVisible = true;
    this.showSeriesStroke = false;
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], LegendItem.prototype, "maxWidth", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], LegendItem.prototype, "paddingX", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], LegendItem.prototype, "paddingY", 2);
__decorateClass([
  Validate(BOOLEAN)
], LegendItem.prototype, "toggleSeriesVisible", 2);
__decorateClass([
  Validate(BOOLEAN)
], LegendItem.prototype, "showSeriesStroke", 2);
var LegendListeners = class {
  constructor() {
    this.legendItemClick = void 0;
    this.legendItemDoubleClick = void 0;
  }
};
__decorateClass([
  Validate(FUNCTION, { optional: true })
], LegendListeners.prototype, "legendItemClick", 2);
var Legend = class {
  constructor(ctx) {
    this.ctx = ctx;
    this.id = createId(this);
    this.group = new Group({
      name: "legend",
      layer: true,
      zIndex: 9
      /* LEGEND_ZINDEX */
    });
    this.itemSelection = Selection.select(this.group, MarkerLabel);
    this.oldSize = [0, 0];
    this.pages = [];
    this.maxPageSize = [0, 0];
    this.paginationTrackingIndex = 0;
    this.item = new LegendItem();
    this.listeners = new LegendListeners();
    this.truncatedItems = /* @__PURE__ */ new Set();
    this._data = [];
    this._enabled = true;
    this.position = "bottom";
    this.maxWidth = void 0;
    this.maxHeight = void 0;
    this.reverseOrder = void 0;
    this.preventHidingAll = void 0;
    this.destroyFns = [];
    this.spacing = 20;
    this.characterWidths = /* @__PURE__ */ new Map();
    this.size = [0, 0];
    this._visible = true;
    this.item.marker.parent = this;
    this.pagination = new Pagination(
      (type) => ctx.updateService.update(type),
      (page) => this.updatePageNumber(page),
      ctx.interactionManager,
      ctx.cursorManager
    );
    this.pagination.attachPagination(this.group);
    this.item.marker.parent = this;
    const bypass = { bypassPause: ["animation"] };
    this.destroyFns.push(
      ctx.interactionManager.addListener("click", (e) => this.checkLegendClick(e), bypass),
      ctx.interactionManager.addListener("dblclick", (e) => this.checkLegendDoubleClick(e), bypass),
      ctx.interactionManager.addListener("hover", (e) => this.handleLegendMouseMove(e)),
      ctx.layoutService.addListener("start-layout", (e) => this.positionLegend(e.shrinkRect)),
      () => this.detachLegend()
    );
  }
  set data(value) {
    this._data = value;
    this.updateGroupVisibility();
  }
  get data() {
    return this._data;
  }
  set enabled(value) {
    this._enabled = value;
    this.updateGroupVisibility();
  }
  get enabled() {
    return this._enabled;
  }
  getOrientation() {
    if (this.orientation !== void 0) {
      return this.orientation;
    }
    switch (this.position) {
      case "right":
      case "left":
        return "vertical";
      case "bottom":
      case "top":
        return "horizontal";
    }
  }
  destroy() {
    this.destroyFns.forEach((f) => f());
  }
  onMarkerShapeChange() {
    this.itemSelection.clear();
    this.group.markDirty(
      this.group,
      2
      /* MINOR */
    );
  }
  getCharacterWidths(font) {
    const { characterWidths } = this;
    if (characterWidths.has(font)) {
      return characterWidths.get(font);
    }
    const cw = {
      "...": HdpiCanvas.getTextSize("...", font).width
    };
    characterWidths.set(font, cw);
    return cw;
  }
  set visible(value) {
    this._visible = value;
    this.updateGroupVisibility();
  }
  get visible() {
    return this._visible;
  }
  updateGroupVisibility() {
    this.group.visible = this.enabled && this.visible && this.data.length > 0;
  }
  attachLegend(node) {
    node.append(this.group);
  }
  detachLegend() {
    var _a;
    (_a = this.group.parent) == null ? void 0 : _a.removeChild(this.group);
  }
  getItemLabel(datum) {
    const {
      ctx: { callbackCache }
    } = this;
    const { formatter } = this.item.label;
    if (formatter) {
      return callbackCache.call(formatter, {
        itemId: datum.itemId,
        value: datum.label.text,
        seriesId: datum.seriesId
      });
    }
    return datum.label.text;
  }
  /**
   * The method is given the desired size of the legend, which only serves as a hint.
   * The vertically oriented legend will take as much horizontal space as needed, but will
   * respect the height constraints, and the horizontal legend will take as much vertical
   * space as needed in an attempt not to exceed the given width.
   * After the layout is done, the {@link size} will contain the actual size of the legend.
   * If the actual size is not the same as the previous actual size, the legend will fire
   * the 'layoutChange' event to communicate that another layout is needed, and the above
   * process should be repeated.
   * @param width
   * @param height
   */
  performLayout(width, height) {
    const {
      paddingX,
      paddingY,
      label,
      maxWidth,
      marker: { size: markerSize, padding: markerPadding, shape: markerShape },
      label: { maxLength = Infinity, fontStyle, fontWeight, fontSize, fontFamily },
      line: itemLine,
      showSeriesStroke
    } = this.item;
    const data = [...this.data];
    if (this.reverseOrder) {
      data.reverse();
    }
    this.itemSelection.update(data);
    const bboxes = [];
    const font = getFont(label);
    const itemMaxWidthPercentage = 0.8;
    const maxItemWidth = maxWidth != null ? maxWidth : width * itemMaxWidthPercentage;
    const paddedMarkerWidth = markerSize + markerPadding + paddingX;
    this.itemSelection.each((markerLabel, datum) => {
      var _a, _b, _c;
      const Marker2 = getMarker(markerShape != null ? markerShape : datum.marker.shape);
      const markerEnabled = (_a = datum.marker.enabled) != null ? _a : this.item.marker.enabled;
      if (!(markerLabel.marker && markerLabel.marker instanceof Marker2)) {
        markerLabel.marker = new Marker2();
      }
      markerLabel.markerSize = markerSize;
      markerLabel.spacing = markerPadding;
      markerLabel.fontStyle = fontStyle;
      markerLabel.fontWeight = fontWeight;
      markerLabel.fontSize = fontSize;
      markerLabel.fontFamily = fontFamily;
      const id = (_b = datum.itemId) != null ? _b : datum.id;
      const labelText = this.getItemLabel(datum);
      const text = (labelText != null ? labelText : "<unknown>").replace(/\r?\n/g, " ");
      markerLabel.text = this.truncate(text, maxLength, maxItemWidth, paddedMarkerWidth, font, id);
      if (showSeriesStroke && datum.line !== void 0) {
        markerLabel.lineVisible = true;
        markerLabel.markerVisible = markerEnabled;
        markerLabel.setSeriesStrokeOffset((_c = itemLine.length) != null ? _c : 5);
      } else {
        markerLabel.lineVisible = false;
        markerLabel.markerVisible = true;
      }
      bboxes.push(markerLabel.computeBBox());
    });
    width = Math.max(1, width);
    height = Math.max(1, height);
    if (!isFinite(width)) {
      return false;
    }
    const size = this.size;
    const oldSize = this.oldSize;
    size[0] = width;
    size[1] = height;
    if (size[0] !== oldSize[0] || size[1] !== oldSize[1]) {
      oldSize[0] = size[0];
      oldSize[1] = size[1];
    }
    const { pages, maxPageHeight, maxPageWidth } = this.updatePagination(bboxes, width, height);
    this.pages = pages;
    this.maxPageSize = [maxPageWidth - paddingX, maxPageHeight - paddingY];
    const pageNumber = this.pagination.currentPage;
    const page = this.pages[pageNumber];
    if (this.pages.length < 1 || !page) {
      this.visible = false;
      return;
    }
    this.visible = true;
    this.updatePositions(pageNumber);
    this.update();
  }
  truncate(text, maxCharLength, maxItemWidth, paddedMarkerWidth, font, id) {
    const ellipsis2 = `...`;
    const textChars = text.split("");
    let addEllipsis = false;
    if (text.length > maxCharLength) {
      text = `${text.substring(0, maxCharLength)}`;
      addEllipsis = true;
    }
    const labelWidth = Math.floor(paddedMarkerWidth + HdpiCanvas.getTextSize(text, font).width);
    if (labelWidth > maxItemWidth) {
      let truncatedText = "";
      const characterWidths = this.getCharacterWidths(font);
      let cumulativeWidth = paddedMarkerWidth + characterWidths[ellipsis2];
      for (const char of textChars) {
        if (!characterWidths[char]) {
          characterWidths[char] = HdpiCanvas.getTextSize(char, font).width;
        }
        cumulativeWidth += characterWidths[char];
        if (cumulativeWidth > maxItemWidth) {
          break;
        }
        truncatedText += char;
      }
      text = truncatedText;
      addEllipsis = true;
    }
    if (addEllipsis) {
      text += ellipsis2;
      this.truncatedItems.add(id);
    } else {
      this.truncatedItems.delete(id);
    }
    return text;
  }
  updatePagination(bboxes, width, height) {
    const orientation = this.getOrientation();
    const trackingIndex = Math.min(this.paginationTrackingIndex, bboxes.length);
    this.pagination.orientation = orientation;
    this.pagination.translationX = 0;
    this.pagination.translationY = 0;
    const { pages, maxPageHeight, maxPageWidth, paginationBBox, paginationVertical } = this.calculatePagination(
      bboxes,
      width,
      height
    );
    const newCurrentPage = pages.findIndex((p) => p.endIndex >= trackingIndex);
    this.pagination.currentPage = Math.min(Math.max(newCurrentPage, 0), pages.length - 1);
    const { paddingX: itemPaddingX, paddingY: itemPaddingY } = this.item;
    const paginationComponentPadding = 8;
    const legendItemsWidth = maxPageWidth - itemPaddingX;
    const legendItemsHeight = maxPageHeight - itemPaddingY;
    let paginationX = 0;
    let paginationY = -paginationBBox.y - this.item.marker.size / 2;
    if (paginationVertical) {
      paginationY += legendItemsHeight + paginationComponentPadding;
    } else {
      paginationX += -paginationBBox.x + legendItemsWidth + paginationComponentPadding;
      paginationY += (legendItemsHeight - paginationBBox.height) / 2;
    }
    this.pagination.translationX = paginationX;
    this.pagination.translationY = paginationY;
    this.pagination.update();
    this.pagination.updateMarkers();
    return {
      maxPageHeight,
      maxPageWidth,
      pages
    };
  }
  calculatePagination(bboxes, width, height) {
    var _a, _b, _c;
    const { paddingX: itemPaddingX, paddingY: itemPaddingY } = this.item;
    const orientation = this.getOrientation();
    const paginationVertical = ["left", "right"].includes(this.position);
    let paginationBBox = this.pagination.computeBBox();
    let lastPassPaginationBBox = new BBox(0, 0, 0, 0);
    let pages = [];
    let maxPageWidth = 0;
    let maxPageHeight = 0;
    let count2 = 0;
    const stableOutput = (lastPassPaginationBBox2) => {
      const { width: width2, height: height2 } = lastPassPaginationBBox2;
      return width2 === paginationBBox.width && height2 === paginationBBox.height;
    };
    const forceResult = this.maxWidth !== void 0 || this.maxHeight !== void 0;
    do {
      if (count2++ > 10) {
        Logger.warn("unable to find stable legend layout.");
        break;
      }
      paginationBBox = lastPassPaginationBBox;
      const maxWidth = width - (paginationVertical ? 0 : paginationBBox.width);
      const maxHeight = height - (paginationVertical ? paginationBBox.height : 0);
      const layout = gridLayout({
        orientation,
        bboxes,
        maxHeight,
        maxWidth,
        itemPaddingY,
        itemPaddingX,
        forceResult
      });
      pages = (_a = layout == null ? void 0 : layout.pages) != null ? _a : [];
      maxPageWidth = (_b = layout == null ? void 0 : layout.maxPageWidth) != null ? _b : 0;
      maxPageHeight = (_c = layout == null ? void 0 : layout.maxPageHeight) != null ? _c : 0;
      const totalPages = pages.length;
      this.pagination.visible = totalPages > 1;
      this.pagination.totalPages = totalPages;
      this.pagination.update();
      lastPassPaginationBBox = this.pagination.computeBBox();
      if (!this.pagination.visible) {
        break;
      }
    } while (!stableOutput(lastPassPaginationBBox));
    return { maxPageWidth, maxPageHeight, pages, paginationBBox, paginationVertical };
  }
  updatePositions(pageNumber = 0) {
    const {
      item: { paddingY },
      itemSelection,
      pages
    } = this;
    if (pages.length < 1 || !pages[pageNumber]) {
      return;
    }
    const { columns, startIndex: visibleStart, endIndex: visibleEnd } = pages[pageNumber];
    let x = 0;
    let y = 0;
    const columnCount = columns.length;
    const rowCount = columns[0].indices.length;
    const horizontal = this.getOrientation() === "horizontal";
    const itemHeight = columns[0].bboxes[0].height + paddingY;
    const rowSumColumnWidths = [];
    itemSelection.each((markerLabel, _, i) => {
      var _a, _b;
      if (i < visibleStart || i > visibleEnd) {
        markerLabel.visible = false;
        return;
      }
      const pageIndex = i - visibleStart;
      let columnIndex = 0;
      let rowIndex = 0;
      if (horizontal) {
        columnIndex = pageIndex % columnCount;
        rowIndex = Math.floor(pageIndex / columnCount);
      } else {
        columnIndex = Math.floor(pageIndex / rowCount);
        rowIndex = pageIndex % rowCount;
      }
      markerLabel.visible = true;
      const column = columns[columnIndex];
      if (!column) {
        return;
      }
      y = itemHeight * rowIndex;
      x = (_a = rowSumColumnWidths[rowIndex]) != null ? _a : 0;
      rowSumColumnWidths[rowIndex] = ((_b = rowSumColumnWidths[rowIndex]) != null ? _b : 0) + column.columnWidth;
      markerLabel.translationX = Math.floor(x);
      markerLabel.translationY = Math.floor(y);
    });
  }
  updatePageNumber(pageNumber) {
    const { pages } = this;
    const { startIndex, endIndex } = pages[pageNumber];
    if (startIndex === 0) {
      this.paginationTrackingIndex = 0;
    } else if (pageNumber === pages.length - 1) {
      this.paginationTrackingIndex = endIndex;
    } else {
      this.paginationTrackingIndex = Math.floor((startIndex + endIndex) / 2);
    }
    this.pagination.update();
    this.pagination.updateMarkers();
    this.updatePositions(pageNumber);
    this.ctx.updateService.update(
      5
      /* SCENE_RENDER */
    );
  }
  update() {
    const {
      label: { color },
      marker: itemMarker,
      line: itemLine,
      showSeriesStroke
    } = this.item;
    this.itemSelection.each((markerLabel, datum) => {
      var _a, _b;
      const marker = datum.marker;
      markerLabel.markerFill = marker.fill;
      markerLabel.markerStroke = marker.stroke;
      markerLabel.markerStrokeWidth = (_a = itemMarker.strokeWidth) != null ? _a : Math.min(2, marker.strokeWidth);
      markerLabel.markerFillOpacity = marker.fillOpacity;
      markerLabel.markerStrokeOpacity = marker.strokeOpacity;
      markerLabel.opacity = datum.enabled ? 1 : 0.5;
      markerLabel.color = color;
      const { line } = datum;
      if (showSeriesStroke && line !== void 0) {
        markerLabel.lineStroke = line.stroke;
        markerLabel.lineStrokeOpacity = line.strokeOpacity;
        markerLabel.lineStrokeWidth = (_b = itemLine.strokeWidth) != null ? _b : Math.min(2, line.strokeWidth);
        markerLabel.lineLineDash = line.lineDash;
      }
    });
  }
  getDatumForPoint(x, y) {
    const visibleChildBBoxes = [];
    const closestLeftTop = { dist: Infinity, datum: void 0 };
    for (const child of this.group.children) {
      if (!child.visible)
        continue;
      if (!(child instanceof MarkerLabel))
        continue;
      const childBBox = child.computeBBox();
      childBBox.grow(this.item.paddingX / 2, "horizontal");
      childBBox.grow(this.item.paddingY / 2, "vertical");
      if (childBBox.containsPoint(x, y)) {
        return child.datum;
      }
      const distX = x - childBBox.x - this.item.paddingX / 2;
      const distY = y - childBBox.y - this.item.paddingY / 2;
      const dist = __pow(distX, 2) + __pow(distY, 2);
      const toTheLeftTop = distX >= 0 && distY >= 0;
      if (toTheLeftTop && dist < closestLeftTop.dist) {
        closestLeftTop.dist = dist;
        closestLeftTop.datum = child.datum;
      }
      visibleChildBBoxes.push(childBBox);
    }
    const pageBBox = BBox.merge(visibleChildBBoxes);
    if (!pageBBox.containsPoint(x, y)) {
      return void 0;
    }
    return closestLeftTop.datum;
  }
  computeBBox() {
    return this.group.computeBBox();
  }
  computePagedBBox() {
    const actualBBox = this.group.computeBBox();
    if (this.pages.length <= 1) {
      return actualBBox;
    }
    const [maxPageWidth, maxPageHeight] = this.maxPageSize;
    actualBBox.height = Math.max(maxPageHeight, actualBBox.height);
    actualBBox.width = Math.max(maxPageWidth, actualBBox.width);
    return actualBBox;
  }
  checkLegendClick(event) {
    const {
      listeners: { legendItemClick },
      ctx: { chartService, highlightManager },
      item: { toggleSeriesVisible },
      preventHidingAll
    } = this;
    const { offsetX, offsetY } = event;
    const legendBBox = this.computeBBox();
    const pointerInsideLegend = this.group.visible && legendBBox.containsPoint(offsetX, offsetY);
    const datum = this.getDatumForPoint(offsetX, offsetY);
    if (!pointerInsideLegend || !datum) {
      return;
    }
    const { id, itemId, enabled } = datum;
    const series = chartService.series.find((s) => s.id === id);
    if (!series) {
      return;
    }
    event.consume();
    let newEnabled = enabled;
    if (toggleSeriesVisible) {
      newEnabled = !enabled;
      if (preventHidingAll && !newEnabled) {
        const numVisibleItems = chartService.series.flatMap((series2) => series2.getLegendData("category")).filter((datum2) => datum2.enabled).length;
        if (numVisibleItems < 2) {
          newEnabled = true;
        }
      }
      this.ctx.chartEventManager.legendItemClick(series, itemId, newEnabled, datum.legendItemName);
    }
    if (!newEnabled) {
      highlightManager.updateHighlight(this.id);
    } else {
      highlightManager.updateHighlight(this.id, {
        series,
        itemId,
        datum: void 0
      });
    }
    this.ctx.updateService.update(1, { forceNodeDataRefresh: true });
    legendItemClick == null ? void 0 : legendItemClick({ type: "click", enabled: newEnabled, itemId, seriesId: series.id });
  }
  checkLegendDoubleClick(event) {
    var _a;
    const {
      listeners: { legendItemDoubleClick },
      ctx: { chartService },
      item: { toggleSeriesVisible }
    } = this;
    const { offsetX, offsetY } = event;
    if (chartService.mode === "integrated") {
      return;
    }
    const legendBBox = this.computeBBox();
    const pointerInsideLegend = this.group.visible && legendBBox.containsPoint(offsetX, offsetY);
    const datum = this.getDatumForPoint(offsetX, offsetY);
    if (!pointerInsideLegend || !datum) {
      return;
    }
    const { id, itemId, seriesId } = datum;
    const series = chartService.series.find((s) => s.id === id);
    if (!series) {
      return;
    }
    event.consume();
    if (toggleSeriesVisible) {
      const legendData = chartService.series.flatMap((series2) => series2.getLegendData("category"));
      const numVisibleItems = legendData.filter((datum2) => datum2.enabled).length;
      const clickedItem = legendData.find((d) => d.itemId === itemId && d.seriesId === seriesId);
      this.ctx.chartEventManager.legendItemDoubleClick(
        series,
        itemId,
        (_a = clickedItem == null ? void 0 : clickedItem.enabled) != null ? _a : false,
        numVisibleItems,
        clickedItem == null ? void 0 : clickedItem.legendItemName
      );
    }
    this.ctx.updateService.update(1, { forceNodeDataRefresh: true });
    legendItemDoubleClick == null ? void 0 : legendItemDoubleClick({ type: "dblclick", enabled: true, itemId, seriesId: series.id });
  }
  handleLegendMouseMove(event) {
    var _a;
    const {
      enabled,
      item: { toggleSeriesVisible },
      listeners
    } = this;
    if (!enabled) {
      return;
    }
    const legendBBox = this.computeBBox();
    const { pageX, pageY, offsetX, offsetY } = event;
    const pointerInsideLegend = this.group.visible && legendBBox.containsPoint(offsetX, offsetY);
    if (!pointerInsideLegend) {
      this.ctx.cursorManager.updateCursor(this.id);
      this.ctx.highlightManager.updateHighlight(this.id);
      this.ctx.tooltipManager.removeTooltip(this.id);
      return;
    }
    event.consume();
    const datum = this.getDatumForPoint(offsetX, offsetY);
    const pointerOverLegendDatum = pointerInsideLegend && datum !== void 0;
    if (!pointerOverLegendDatum) {
      this.ctx.cursorManager.updateCursor(this.id);
      this.ctx.highlightManager.updateHighlight(this.id);
      return;
    }
    const series = datum ? this.ctx.chartService.series.find((series2) => series2.id === (datum == null ? void 0 : datum.id)) : void 0;
    if (datum && this.truncatedItems.has((_a = datum.itemId) != null ? _a : datum.id)) {
      this.ctx.tooltipManager.updateTooltip(
        this.id,
        { pageX, pageY, offsetX, offsetY, event, showArrow: false, addCustomClass: false },
        toTooltipHtml({ content: this.getItemLabel(datum) })
      );
    } else {
      this.ctx.tooltipManager.removeTooltip(this.id);
    }
    if (toggleSeriesVisible || listeners.legendItemClick != null || listeners.legendItemDoubleClick != null) {
      this.ctx.cursorManager.updateCursor(this.id, "pointer");
    }
    if ((datum == null ? void 0 : datum.enabled) && series) {
      this.ctx.highlightManager.updateHighlight(this.id, {
        series,
        itemId: datum == null ? void 0 : datum.itemId,
        datum: void 0
      });
    } else {
      this.ctx.highlightManager.updateHighlight(this.id);
    }
  }
  positionLegend(shrinkRect) {
    const newShrinkRect = shrinkRect.clone();
    if (!this.enabled || !this.data.length) {
      return { shrinkRect: newShrinkRect };
    }
    const [legendWidth, legendHeight] = this.calculateLegendDimensions(shrinkRect);
    this.group.translationX = 0;
    this.group.translationY = 0;
    this.performLayout(legendWidth, legendHeight);
    const legendBBox = this.computePagedBBox();
    const calculateTranslationPerpendicularDimension = () => {
      switch (this.position) {
        case "top":
        case "left":
          return 0;
        case "bottom":
          return shrinkRect.height - legendBBox.height;
        case "right":
        default:
          return shrinkRect.width - legendBBox.width;
      }
    };
    if (this.visible) {
      let translationX;
      let translationY;
      switch (this.position) {
        case "top":
        case "bottom":
          translationX = (shrinkRect.width - legendBBox.width) / 2;
          translationY = calculateTranslationPerpendicularDimension();
          newShrinkRect.shrink(legendBBox.height, this.position);
          break;
        case "left":
        case "right":
        default:
          translationX = calculateTranslationPerpendicularDimension();
          translationY = (shrinkRect.height - legendBBox.height) / 2;
          newShrinkRect.shrink(legendBBox.width, this.position);
      }
      this.group.translationX = Math.floor(-legendBBox.x + shrinkRect.x + translationX);
      this.group.translationY = Math.floor(-legendBBox.y + shrinkRect.y + translationY);
    }
    if (this.visible && this.enabled && this.data.length) {
      const legendPadding = this.spacing;
      newShrinkRect.shrink(legendPadding, this.position);
      const legendPositionedBBox = legendBBox.clone();
      legendPositionedBBox.x += this.group.translationX;
      legendPositionedBBox.y += this.group.translationY;
      this.ctx.tooltipManager.updateExclusiveRect(this.id, legendPositionedBBox);
    } else {
      this.ctx.tooltipManager.updateExclusiveRect(this.id);
    }
    return { shrinkRect: newShrinkRect };
  }
  calculateLegendDimensions(shrinkRect) {
    const { width, height } = shrinkRect;
    const aspectRatio = width / height;
    const maxCoefficient = 0.5;
    const minHeightCoefficient = 0.2;
    const minWidthCoefficient = 0.25;
    let legendWidth, legendHeight;
    switch (this.position) {
      case "top":
      case "bottom":
        const heightCoefficient = aspectRatio < 1 ? Math.min(maxCoefficient, minHeightCoefficient * (1 / aspectRatio)) : minHeightCoefficient;
        legendWidth = this.maxWidth ? Math.min(this.maxWidth, width) : width;
        legendHeight = this.maxHeight ? Math.min(this.maxHeight, height) : Math.round(height * heightCoefficient);
        break;
      case "left":
      case "right":
      default:
        const widthCoefficient = aspectRatio > 1 ? Math.min(maxCoefficient, minWidthCoefficient * aspectRatio) : minWidthCoefficient;
        legendWidth = this.maxWidth ? Math.min(this.maxWidth, width) : Math.round(width * widthCoefficient);
        legendHeight = this.maxHeight ? Math.min(this.maxHeight, height) : height;
    }
    return [legendWidth, legendHeight];
  }
};
Legend.className = "Legend";
__decorateClass([
  Validate(BOOLEAN)
], Legend.prototype, "_enabled", 2);
__decorateClass([
  Validate(POSITION)
], Legend.prototype, "position", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], Legend.prototype, "maxWidth", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], Legend.prototype, "maxHeight", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], Legend.prototype, "reverseOrder", 2);
__decorateClass([
  Validate(UNION(["horizontal", "vertical"], "an orientation"), { optional: true })
], Legend.prototype, "orientation", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], Legend.prototype, "preventHidingAll", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], Legend.prototype, "spacing", 2);
var Overlay = class {
  constructor(className, parentElement) {
    this.className = className;
    this.parentElement = parentElement;
  }
  show(rect) {
    var _a, _b;
    if (!this.element) {
      this.element = this.createElement("div");
      this.element.className = this.className;
    }
    const { element: element2 } = this;
    element2.style.position = "absolute";
    element2.style.left = `${rect.x}px`;
    element2.style.top = `${rect.y}px`;
    element2.style.width = `${rect.width}px`;
    element2.style.height = `${rect.height}px`;
    if (this.renderer) {
      element2.innerHTML = this.renderer();
    } else {
      const content = this.createElement("div");
      content.style.alignItems = "center";
      content.style.boxSizing = "border-box";
      content.style.display = "flex";
      content.style.justifyContent = "center";
      content.style.margin = "8px";
      content.style.height = "100%";
      content.style.font = "12px Verdana, sans-serif";
      content.innerText = (_a = this.text) != null ? _a : "No data to display";
      element2.replaceChildren(content);
    }
    (_b = this.parentElement) == null ? void 0 : _b.append(element2);
  }
  hide() {
    var _a;
    (_a = this.element) == null ? void 0 : _a.remove();
    this.element = void 0;
  }
  createElement(tagName, options) {
    return this.parentElement.ownerDocument.createElement(tagName, options);
  }
};
__decorateClass([
  Validate(FUNCTION, { optional: true })
], Overlay.prototype, "renderer", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], Overlay.prototype, "text", 2);
var ChartOverlays = class {
  constructor(parent) {
    this.noData = new Overlay("ag-chart-no-data-overlay", parent);
    this.noVisibleSeries = new Overlay("ag-chart-no-visible-series", parent);
    this.noVisibleSeries.text = "No visible series";
  }
  destroy() {
    this.noData.hide();
    this.noVisibleSeries.hide();
  }
};
function deepMerge(target, source) {
  if (isPlainObject2(target) && isPlainObject2(source)) {
    const result = {};
    Object.keys(target).forEach((key) => {
      if (key in source) {
        result[key] = deepMerge(target[key], source[key]);
      } else {
        result[key] = target[key];
      }
    });
    Object.keys(source).forEach((key) => {
      if (!(key in target)) {
        result[key] = source[key];
      }
    });
    return result;
  }
  if (Array.isArray(target) && !Array.isArray(source) || isObjectLike2(target) && !isObjectLike2(source)) {
    return target;
  }
  return source;
}
function isObjectLike2(value) {
  return typeof value === "object" && value !== null;
}
function isObject2(value) {
  return isObjectLike2(value) && !Array.isArray(value);
}
function isPlainObject2(x) {
  return isObject2(x) && x.constructor === Object;
}
function mergeDefaults(...sources) {
  var _a;
  const target = {};
  for (const source of sources) {
    if (!source)
      continue;
    const keys = isDecoratedObject(source) ? listDecoratedProperties(source) : Object.keys(source);
    for (const key of keys) {
      if (isObject2(target[key]) && isObject2(source[key])) {
        target[key] = mergeDefaults(target[key], source[key]);
      } else {
        (_a = target[key]) != null ? _a : target[key] = source[key];
      }
    }
  }
  return target;
}
function partialAssign(keysToCopy, target, source) {
  if (source === void 0) {
    return target;
  }
  for (const key of keysToCopy) {
    const value = source[key];
    if (value !== void 0) {
      target[key] = value;
    }
  }
  return target;
}
function sumValues(values, accumulator = [0, 0]) {
  for (const value of values) {
    if (typeof value !== "number") {
      continue;
    }
    if (value < 0) {
      accumulator[0] += value;
    }
    if (value > 0) {
      accumulator[1] += value;
    }
  }
  return accumulator;
}
function sum(scope, id, matchGroupId) {
  const result = {
    id,
    scopes: [scope.id],
    matchGroupIds: [matchGroupId],
    type: "aggregate",
    aggregateFunction: (values) => sumValues(values)
  };
  return result;
}
function groupSum(scope, id, matchGroupId) {
  return {
    id,
    scopes: [scope.id],
    type: "aggregate",
    matchGroupIds: matchGroupId ? [matchGroupId] : void 0,
    aggregateFunction: (values) => sumValues(values),
    groupAggregateFunction: (next, acc = [0, 0]) => {
      var _a, _b;
      acc[0] += (_a = next == null ? void 0 : next[0]) != null ? _a : 0;
      acc[1] += (_b = next == null ? void 0 : next[1]) != null ? _b : 0;
      return acc;
    }
  };
}
function range2(scope, id, matchGroupId) {
  const result = {
    id,
    scopes: [scope.id],
    matchGroupIds: [matchGroupId],
    type: "aggregate",
    aggregateFunction: (values) => extendDomain(values)
  };
  return result;
}
function count(scope, id) {
  const result = {
    id,
    scopes: [scope.id],
    type: "aggregate",
    aggregateFunction: () => [0, 1]
  };
  return result;
}
function groupCount(scope, id) {
  return {
    id,
    scopes: [scope.id],
    type: "aggregate",
    aggregateFunction: () => [0, 1],
    groupAggregateFunction: (next, acc = [0, 0]) => {
      var _a, _b;
      acc[0] += (_a = next == null ? void 0 : next[0]) != null ? _a : 0;
      acc[1] += (_b = next == null ? void 0 : next[1]) != null ? _b : 0;
      return acc;
    }
  };
}
function average(scope, id, matchGroupId) {
  const result = {
    id,
    scopes: [scope.id],
    matchGroupIds: [matchGroupId],
    type: "aggregate",
    aggregateFunction: (values) => sumValues(values).map((v) => v / values.length)
  };
  return result;
}
function groupAverage(scope, id, matchGroupId) {
  const result = {
    id,
    scopes: [scope.id],
    matchGroupIds: matchGroupId ? [matchGroupId] : void 0,
    type: "aggregate",
    aggregateFunction: (values) => sumValues(values),
    groupAggregateFunction: (next, acc = [0, 0, -1]) => {
      var _a, _b;
      acc[0] += (_a = next == null ? void 0 : next[0]) != null ? _a : 0;
      acc[1] += (_b = next == null ? void 0 : next[1]) != null ? _b : 0;
      acc[2]++;
      return acc;
    },
    finalFunction: (acc = [0, 0, 0]) => {
      const result2 = acc[0] + acc[1];
      if (result2 >= 0) {
        return [0, result2 / acc[2]];
      }
      return [result2 / acc[2], 0];
    }
  };
  return result;
}
function area(scope, id, aggFn, matchGroupId) {
  const result = {
    id,
    scopes: [scope.id],
    matchGroupIds: matchGroupId ? [matchGroupId] : void 0,
    type: "aggregate",
    aggregateFunction: (values, keyRange = []) => {
      const keyWidth = keyRange[1] - keyRange[0];
      return aggFn.aggregateFunction(values).map((v) => v / keyWidth);
    }
  };
  if (aggFn.groupAggregateFunction) {
    result.groupAggregateFunction = aggFn.groupAggregateFunction;
  }
  return result;
}
function accumulatedValue(onlyPositive) {
  return () => {
    let value = 0;
    return (datum) => {
      if (typeof datum !== "number")
        return datum;
      if (isNaN(datum))
        return datum;
      value += onlyPositive ? Math.max(0, datum) : datum;
      return value;
    };
  };
}
function trailingAccumulatedValue() {
  return () => {
    let value = 0;
    return (datum) => {
      if (typeof datum !== "number")
        return datum;
      if (isNaN(datum))
        return datum;
      const trailingValue2 = value;
      value += datum;
      return trailingValue2;
    };
  };
}
var memorizedFns = /* @__PURE__ */ new Map();
function memo(params, fnGenerator) {
  var _a, _b, _c;
  const serialisedParams = JSON.stringify(params, null, 0);
  if (!memorizedFns.has(fnGenerator)) {
    memorizedFns.set(fnGenerator, /* @__PURE__ */ new Map());
  }
  if (!((_a = memorizedFns.get(fnGenerator)) == null ? void 0 : _a.has(serialisedParams))) {
    (_b = memorizedFns.get(fnGenerator)) == null ? void 0 : _b.set(serialisedParams, fnGenerator(params));
  }
  return (_c = memorizedFns.get(fnGenerator)) == null ? void 0 : _c.get(serialisedParams);
}
var SMALLEST_KEY_INTERVAL = {
  type: "reducer",
  property: "smallestKeyInterval",
  initialValue: Infinity,
  reducer: () => {
    let prevX = NaN;
    return (smallestSoFar = Infinity, next) => {
      const nextX = next.keys[0];
      const interval = Math.abs(nextX - prevX);
      prevX = nextX;
      if (!isNaN(interval) && interval > 0 && interval < smallestSoFar) {
        return interval;
      }
      return smallestSoFar;
    };
  }
};
var AGG_VALUES_EXTENT = {
  type: "processor",
  property: "aggValuesExtent",
  calculate: (processedData) => {
    var _a, _b, _c, _d;
    const result = [...(_b = (_a = processedData.domain.aggValues) == null ? void 0 : _a[0]) != null ? _b : [0, 0]];
    for (const [min, max] of (_d = (_c = processedData.domain.aggValues) == null ? void 0 : _c.slice(1)) != null ? _d : []) {
      if (min < result[0]) {
        result[0] = min;
      }
      if (max > result[1]) {
        result[1] = max;
      }
    }
    return result;
  }
};
var SORT_DOMAIN_GROUPS = {
  type: "processor",
  property: "sortedGroupDomain",
  calculate: ({ domain: { groups } }) => {
    if (groups == null)
      return void 0;
    return [...groups].sort((a, b) => {
      for (let i = 0; i < a.length; i++) {
        const result = a[i] - b[i];
        if (result !== 0) {
          return result;
        }
      }
      return 0;
    });
  }
};
function normaliseFnBuilder({ normaliseTo, mode }) {
  const normalise = (val, extent2) => {
    const result = val * normaliseTo / extent2;
    if (result >= 0) {
      return Math.min(normaliseTo, result);
    }
    return Math.max(-normaliseTo, result);
  };
  return () => () => (values, valueIndexes) => {
    const valuesExtent = [0, 0];
    for (const valueIdx of valueIndexes) {
      const value = values[valueIdx];
      const valIdx = value < 0 ? 0 : 1;
      if (mode === "sum") {
        valuesExtent[valIdx] += value;
      } else if (valIdx === 0) {
        valuesExtent[valIdx] = Math.min(valuesExtent[valIdx], value);
      } else {
        valuesExtent[valIdx] = Math.max(valuesExtent[valIdx], value);
      }
    }
    const extent2 = Math.max(Math.abs(valuesExtent[0]), valuesExtent[1]);
    for (const valueIdx of valueIndexes) {
      values[valueIdx] = normalise(values[valueIdx], extent2);
    }
  };
}
function normaliseGroupTo(scope, matchGroupIds, normaliseTo, mode = "sum") {
  return {
    scopes: [scope.id],
    type: "group-value-processor",
    matchGroupIds,
    adjust: memo({ normaliseTo, mode }, normaliseFnBuilder)
  };
}
function normalisePropertyFnBuilder({
  normaliseTo,
  zeroDomain,
  rangeMin,
  rangeMax
}) {
  const normaliseSpan = normaliseTo[1] - normaliseTo[0];
  const normalise = (val, start, span) => {
    const result = normaliseTo[0] + (val - start) / span * normaliseSpan;
    if (span === 0)
      return zeroDomain;
    if (result >= normaliseTo[1])
      return normaliseTo[1];
    if (result < normaliseTo[0])
      return normaliseTo[0];
    return result;
  };
  return () => (pData, pIdx) => {
    let [start, end] = pData.domain.values[pIdx];
    if (rangeMin != null)
      start = rangeMin;
    if (rangeMax != null)
      end = rangeMax;
    const span = end - start;
    pData.domain.values[pIdx] = [normaliseTo[0], normaliseTo[1]];
    for (const group2 of pData.data) {
      let groupValues = group2.values;
      if (pData.type === "ungrouped") {
        groupValues = [groupValues];
      }
      for (const values of groupValues) {
        values[pIdx] = normalise(values[pIdx], start, span);
      }
    }
  };
}
function normalisePropertyTo(scope, property, normaliseTo, zeroDomain, rangeMin, rangeMax) {
  return {
    scopes: [scope.id],
    type: "property-value-processor",
    property,
    adjust: memo({ normaliseTo, rangeMin, rangeMax, zeroDomain }, normalisePropertyFnBuilder)
  };
}
function animationValidation(scope, valueKeyIds = []) {
  return {
    type: "processor",
    scopes: [scope.id],
    property: "animationValidation",
    calculate(result) {
      var _a;
      const { keys, values } = result.defs;
      const { input, data } = result;
      let uniqueKeys = true;
      let orderedKeys = true;
      const valueKeys = [];
      for (let k = 0; k < values.length; k++) {
        if (!((_a = values[k].scopes) == null ? void 0 : _a.some((s) => s === scope.id)))
          continue;
        if (!valueKeyIds.some((v) => values[k].id === v))
          continue;
        valueKeys.push([k, values[k]]);
      }
      const processKey = (idx, def, type) => {
        var _a2;
        if (def.valueType === "category") {
          const keyValues = result.domain[type][idx];
          uniqueKeys && (uniqueKeys = keyValues.length === input.count);
          return;
        }
        let lastValue = (_a2 = data[0]) == null ? void 0 : _a2[type][idx];
        for (let d = 1; (uniqueKeys || orderedKeys) && d < data.length; d++) {
          const keyValue = data[d][type][idx];
          orderedKeys && (orderedKeys = lastValue <= keyValue);
          uniqueKeys && (uniqueKeys = lastValue !== keyValue);
          lastValue = keyValue;
        }
      };
      for (let k = 0; (uniqueKeys || orderedKeys) && k < keys.length; k++) {
        processKey(k, keys[k], "keys");
      }
      for (let k = 0; (uniqueKeys || orderedKeys) && k < valueKeys.length; k++) {
        const [idx, key] = valueKeys[k];
        processKey(idx, key, "values");
      }
      return { uniqueKeys, orderedKeys };
    }
  };
}
function buildGroupAccFn({ mode, separateNegative }) {
  return () => () => (values, valueIndexes) => {
    const acc = [0, 0];
    for (const valueIdx of valueIndexes) {
      const currentVal = values[valueIdx];
      const accIndex = isNegative(currentVal) && separateNegative ? 0 : 1;
      if (typeof currentVal !== "number" || isNaN(currentVal))
        continue;
      if (mode === "normal")
        acc[accIndex] += currentVal;
      values[valueIdx] = acc[accIndex];
      if (mode === "trailing")
        acc[accIndex] += currentVal;
    }
  };
}
function buildGroupWindowAccFn({ mode, sum: sum2 }) {
  return () => {
    const lastValues = [];
    let firstRow = true;
    return () => {
      return (values, valueIndexes) => {
        let acc = 0;
        for (const valueIdx of valueIndexes) {
          const currentVal = values[valueIdx];
          const lastValue = firstRow && sum2 === "current" ? 0 : lastValues[valueIdx];
          lastValues[valueIdx] = currentVal;
          const sumValue = sum2 === "current" ? currentVal : lastValue;
          if (typeof currentVal !== "number" || isNaN(currentVal)) {
            values[valueIdx] = acc;
            continue;
          }
          if (typeof lastValue !== "number" || isNaN(lastValue)) {
            values[valueIdx] = acc;
            continue;
          }
          if (mode === "normal")
            acc += sumValue;
          values[valueIdx] = acc;
          if (mode === "trailing")
            acc += sumValue;
        }
        firstRow = false;
      };
    };
  };
}
function accumulateGroup(scope, matchGroupId, mode, sum2, separateNegative = false) {
  let adjust;
  if (mode.startsWith("window")) {
    const modeParam = mode.endsWith("-trailing") ? "trailing" : "normal";
    adjust = memo({ mode: modeParam, sum: sum2 }, buildGroupWindowAccFn);
  } else {
    adjust = memo({ mode, separateNegative }, buildGroupAccFn);
  }
  return {
    scopes: [scope.id],
    type: "group-value-processor",
    matchGroupIds: [matchGroupId],
    adjust
  };
}
function diff(previousData, updateMovedDatums = true) {
  return {
    type: "processor",
    property: "diff",
    calculate: (processedData) => {
      const diff2 = {
        changed: false,
        moved: [],
        added: [],
        updated: [],
        removed: [],
        addedIndices: [],
        updatedIndices: [],
        removedIndices: []
      };
      const moved = /* @__PURE__ */ new Map();
      const added = /* @__PURE__ */ new Map();
      const updated = /* @__PURE__ */ new Map();
      const removed = /* @__PURE__ */ new Map();
      const addedIndices = /* @__PURE__ */ new Map();
      const updatedIndices = /* @__PURE__ */ new Map();
      const removedIndices = /* @__PURE__ */ new Map();
      for (let i = 0; i < Math.max(previousData.data.length, processedData.data.length); i++) {
        const prev = previousData.data[i];
        const datum = processedData.data[i];
        const prevId = prev ? createDatumId(prev.keys) : "";
        const datumId = datum ? createDatumId(datum.keys) : "";
        if (prevId === datumId) {
          if (!arraysEqual(prev.values, datum.values)) {
            updated.set(datumId, datum);
            updatedIndices.set(datumId, i);
          }
          continue;
        }
        if (removed.has(datumId)) {
          if (updateMovedDatums || !arraysEqual(removed.get(datumId).values, datum.values)) {
            updated.set(datumId, datum);
            updatedIndices.set(datumId, i);
            moved.set(datumId, datum);
          }
          removed.delete(datumId);
          removedIndices.delete(datumId);
        } else if (datum) {
          added.set(datumId, datum);
          addedIndices.set(datumId, i);
        }
        if (added.has(prevId)) {
          if (updateMovedDatums || !arraysEqual(added.get(prevId).values, prev.values)) {
            updated.set(prevId, prev);
            updatedIndices.set(prevId, i);
            moved.set(prevId, prev);
          }
          added.delete(prevId);
          addedIndices.delete(prevId);
        } else if (prev) {
          updated.delete(prevId);
          updatedIndices.delete(prevId);
          removed.set(prevId, prev);
          removedIndices.set(prevId, i);
        }
      }
      diff2.added = Array.from(added.keys());
      diff2.updated = Array.from(updated.keys());
      diff2.removed = Array.from(removed.keys());
      diff2.moved = Array.from(moved.keys());
      diff2.addedIndices = Array.from(addedIndices.values());
      diff2.updatedIndices = Array.from(updatedIndices.values());
      diff2.removedIndices = Array.from(removedIndices.values());
      diff2.changed = diff2.added.length > 0 || diff2.updated.length > 0 || diff2.removed.length > 0;
      return diff2;
    }
  };
}
function createDatumId(keys) {
  return keys.join("___");
}
var SeriesNodePickMode = /* @__PURE__ */ ((SeriesNodePickMode2) => {
  SeriesNodePickMode2[SeriesNodePickMode2["EXACT_SHAPE_MATCH"] = 0] = "EXACT_SHAPE_MATCH";
  SeriesNodePickMode2[SeriesNodePickMode2["NEAREST_BY_MAIN_AXIS_FIRST"] = 1] = "NEAREST_BY_MAIN_AXIS_FIRST";
  SeriesNodePickMode2[SeriesNodePickMode2["NEAREST_BY_MAIN_CATEGORY_AXIS_FIRST"] = 2] = "NEAREST_BY_MAIN_CATEGORY_AXIS_FIRST";
  SeriesNodePickMode2[SeriesNodePickMode2["NEAREST_NODE"] = 3] = "NEAREST_NODE";
  return SeriesNodePickMode2;
})(SeriesNodePickMode || {});
function basicContinuousCheckDatumValidation(v) {
  return checkDatum(v, true) != null;
}
function basicDiscreteCheckDatumValidation(v) {
  return checkDatum(v, false) != null;
}
function keyProperty(scope, propName, continuous, opts = {}) {
  const result = __spreadValues({
    scopes: [scope.id],
    property: propName,
    type: "key",
    valueType: continuous ? "range" : "category",
    validation: continuous ? basicContinuousCheckDatumValidation : basicDiscreteCheckDatumValidation
  }, opts);
  return result;
}
function valueProperty(scope, propName, continuous, opts = {}) {
  const result = __spreadValues({
    scopes: [scope.id],
    property: propName,
    type: "value",
    valueType: continuous ? "range" : "category",
    validation: continuous ? basicContinuousCheckDatumValidation : basicDiscreteCheckDatumValidation
  }, opts);
  return result;
}
function rangedValueProperty(scope, propName, opts = {}) {
  const _a = opts, { min = -Infinity, max = Infinity } = _a, defOpts = __objRest(_a, ["min", "max"]);
  return __spreadValues({
    scopes: [scope.id],
    type: "value",
    property: propName,
    valueType: "range",
    validation: basicContinuousCheckDatumValidation,
    processor: () => (datum) => {
      if (typeof datum !== "number")
        return datum;
      if (isNaN(datum))
        return datum;
      return Math.min(Math.max(datum, min), max);
    }
  }, defOpts);
}
function trailingValueProperty(scope, propName, continuous, opts = {}) {
  const result = __spreadProps(__spreadValues({}, valueProperty(scope, propName, continuous, opts)), {
    processor: trailingValue()
  });
  return result;
}
function trailingValue() {
  return () => {
    let value = 0;
    return (datum) => {
      const trailingValue2 = value;
      value = datum;
      return trailingValue2;
    };
  };
}
function accumulativeValueProperty(scope, propName, continuous, opts = {}) {
  const _a = opts, { onlyPositive } = _a, defOpts = __objRest(_a, ["onlyPositive"]);
  const result = __spreadProps(__spreadValues({}, valueProperty(scope, propName, continuous, defOpts)), {
    processor: accumulatedValue(onlyPositive)
  });
  return result;
}
function trailingAccumulatedValueProperty(scope, propName, continuous, opts = {}) {
  const result = __spreadProps(__spreadValues({}, valueProperty(scope, propName, continuous, opts)), {
    processor: trailingAccumulatedValue()
  });
  return result;
}
function groupAccumulativeValueProperty(scope, propName, continuous, mode, sum2 = "current", opts) {
  return [
    valueProperty(scope, propName, continuous, opts),
    accumulateGroup(scope, opts.groupId, mode, sum2, opts.separateNegative),
    ...opts.rangeId != null ? [range2(scope, opts.rangeId, opts.groupId)] : []
  ];
}
var SeriesNodeClickEvent = class {
  constructor(type, event, { datum }, series) {
    this.type = type;
    this.event = event;
    this.datum = datum;
    this.seriesId = series.id;
  }
};
var Series = class extends Observable {
  constructor(seriesOpts) {
    super();
    this.destroyFns = [];
    this.seriesGrouping = void 0;
    this.NodeClickEvent = SeriesNodeClickEvent;
    this.internalId = createId(this);
    this.rootGroup = new Group({ name: "seriesRoot", isVirtual: true });
    this.axes = {
      [
        "x"
        /* X */
      ]: void 0,
      [
        "y"
        /* Y */
      ]: void 0
    };
    this.directions = [
      "x",
      "y"
      /* Y */
    ];
    this.nodeDataRefresh = true;
    this.moduleMap = new ModuleMap();
    this._declarationOrder = -1;
    this.seriesListeners = new Listeners();
    const {
      moduleCtx,
      useLabelLayer = false,
      pickModes = [
        1
        /* NEAREST_BY_MAIN_AXIS_FIRST */
      ],
      directionKeys = {},
      directionNames = {},
      contentGroupVirtual = true,
      canHaveAxes = false
    } = seriesOpts;
    this.ctx = moduleCtx;
    this.directionKeys = directionKeys;
    this.directionNames = directionNames;
    this.canHaveAxes = canHaveAxes;
    this.contentGroup = this.rootGroup.appendChild(
      new Group({
        name: `${this.internalId}-content`,
        layer: !contentGroupVirtual,
        isVirtual: contentGroupVirtual,
        zIndex: 4,
        zIndexSubOrder: this.getGroupZIndexSubOrder("data")
      })
    );
    this.highlightGroup = new Group({
      name: `${this.internalId}-highlight`,
      layer: !contentGroupVirtual,
      isVirtual: contentGroupVirtual,
      zIndex: 4,
      zIndexSubOrder: this.getGroupZIndexSubOrder("highlight")
    });
    this.highlightNode = this.highlightGroup.appendChild(new Group({ name: "highlightNode", zIndex: 0 }));
    this.highlightLabel = this.highlightGroup.appendChild(new Group({ name: "highlightLabel", zIndex: 10 }));
    this.pickModes = pickModes;
    this.labelGroup = this.rootGroup.appendChild(
      new Group({
        name: `${this.internalId}-series-labels`,
        layer: useLabelLayer,
        zIndex: 7
        /* SERIES_LABEL_ZINDEX */
      })
    );
    this.annotationGroup = new Group({
      name: `${this.id}-annotation`,
      layer: !contentGroupVirtual,
      isVirtual: contentGroupVirtual,
      zIndex: 4,
      zIndexSubOrder: this.getGroupZIndexSubOrder("annotation")
    });
  }
  get id() {
    var _a, _b;
    return (_b = (_a = this.properties) == null ? void 0 : _a.id) != null ? _b : this.internalId;
  }
  get type() {
    var _a;
    return (_a = this.constructor.type) != null ? _a : "";
  }
  set data(input) {
    this._data = input;
    this.onDataChange();
  }
  get data() {
    var _a;
    return (_a = this._data) != null ? _a : this._chartData;
  }
  set visible(value) {
    this.properties.visible = value;
    this.visibleChanged();
  }
  get visible() {
    return this.properties.visible;
  }
  onDataChange() {
    this.nodeDataRefresh = true;
  }
  setChartData(input) {
    this._chartData = input;
    if (this.data === input) {
      this.onDataChange();
    }
  }
  hasData() {
    const { data } = this;
    return data && (!Array.isArray(data) || data.length > 0);
  }
  onSeriesGroupingChange(prev, next) {
    const { internalId, type, visible, rootGroup, highlightGroup, annotationGroup } = this;
    if (prev) {
      this.ctx.seriesStateManager.deregisterSeries({ id: internalId, type });
    }
    if (next) {
      this.ctx.seriesStateManager.registerSeries({ id: internalId, type, visible, seriesGrouping: next });
    }
    if (this.rootGroup.parent == null)
      return;
    this.ctx.seriesLayerManager.changeGroup({
      internalId,
      type,
      rootGroup,
      highlightGroup,
      annotationGroup,
      getGroupZIndexSubOrder: (type2) => this.getGroupZIndexSubOrder(type2),
      seriesGrouping: next,
      oldGrouping: prev
    });
  }
  getBandScalePadding() {
    return { inner: 1, outer: 0 };
  }
  getGroupZIndexSubOrder(type, subIndex = 0) {
    let mainAdjust = 0;
    switch (type) {
      case "data":
      case "paths":
        break;
      case "labels":
        mainAdjust += 2e4;
        break;
      case "marker":
        mainAdjust += 1e4;
        break;
      case "highlight":
        subIndex += 15e3;
        break;
      case "annotation":
        mainAdjust += 15e3;
        break;
    }
    const main = () => this._declarationOrder + mainAdjust;
    return [main, subIndex];
  }
  addListener(type, listener) {
    return this.seriesListeners.addListener(type, listener);
  }
  dispatch(type, event) {
    this.seriesListeners.dispatch(type, event);
  }
  addChartEventListeners() {
    return;
  }
  destroy() {
    this.destroyFns.forEach((f) => f());
    this.ctx.seriesStateManager.deregisterSeries(this);
    this.ctx.seriesLayerManager.releaseGroup(this);
  }
  getDirectionValues(direction, properties) {
    const resolvedDirection = this.resolveKeyDirection(direction);
    const keys = properties == null ? void 0 : properties[resolvedDirection];
    const values = [];
    if (!keys)
      return values;
    const addValues = (...items) => {
      for (const value of items) {
        if (Array.isArray(value)) {
          addValues(...value);
        } else if (typeof value === "object") {
          addValues(...Object.values(value));
        } else {
          values.push(value);
        }
      }
    };
    addValues(...keys.map((key) => this.properties[key]));
    return values;
  }
  getKeys(direction) {
    return this.getDirectionValues(direction, this.directionKeys);
  }
  getNames(direction) {
    return this.getDirectionValues(direction, this.directionNames);
  }
  resolveKeyDirection(direction) {
    return direction;
  }
  // The union of the series domain ('community') and series-option domains ('enterprise').
  getDomain(direction) {
    const seriesDomain = this.getSeriesDomain(direction);
    const moduleDomains = this.moduleMap.mapValues((module2) => module2.getDomain(direction));
    return seriesDomain.concat(moduleDomains.flat());
  }
  // Indicate that something external changed and we should recalculate nodeData.
  markNodeDataDirty() {
    this.nodeDataRefresh = true;
  }
  visibleChanged() {
    this.ctx.seriesStateManager.registerSeries(this);
  }
  getOpacity() {
    const defaultOpacity = 1;
    const { dimOpacity = 1, enabled = true } = this.properties.highlightStyle.series;
    if (!enabled || dimOpacity === defaultOpacity) {
      return defaultOpacity;
    }
    switch (this.isItemIdHighlighted()) {
      case 0:
      case 1:
        return defaultOpacity;
      case 2:
      default:
        return dimOpacity;
    }
  }
  getStrokeWidth(defaultStrokeWidth) {
    const { strokeWidth, enabled = true } = this.properties.highlightStyle.series;
    if (!enabled || strokeWidth === void 0) {
      return defaultStrokeWidth;
    }
    switch (this.isItemIdHighlighted()) {
      case 1:
        return strokeWidth;
      case 0:
      case 2:
        return defaultStrokeWidth;
    }
  }
  isItemIdHighlighted() {
    var _a, _b;
    const { series } = (_b = (_a = this.ctx.highlightManager) == null ? void 0 : _a.getActiveHighlight()) != null ? _b : {};
    if (series == null) {
      return 0;
    }
    if (series !== this) {
      return 2;
    }
    return 1;
  }
  getModuleTooltipParams() {
    const params = this.moduleMap.mapValues((module2) => module2.getTooltipParams());
    return params.reduce((total, current) => __spreadValues(__spreadValues({}, current), total), {});
  }
  pickNode(point, limitPickModes) {
    const { pickModes, visible, rootGroup } = this;
    if (!visible || !rootGroup.visible) {
      return;
    }
    for (const pickMode of pickModes) {
      if (limitPickModes && !limitPickModes.includes(pickMode)) {
        continue;
      }
      let match;
      switch (pickMode) {
        case 0:
          match = this.pickNodeExactShape(point);
          break;
        case 1:
        case 2:
          match = this.pickNodeMainAxisFirst(
            point,
            pickMode === 2
            /* NEAREST_BY_MAIN_CATEGORY_AXIS_FIRST */
          );
          break;
        case 3:
          match = this.pickNodeClosestDatum(point);
          break;
      }
      if (match) {
        return { pickMode, match: match.datum, distance: match.distance };
      }
    }
  }
  pickNodeExactShape(point) {
    const match = this.contentGroup.pickNode(point.x, point.y);
    return match && { datum: match.datum, distance: 0 };
  }
  pickNodeClosestDatum(_point) {
    throw new Error("AG Charts - Series.pickNodeClosestDatum() not implemented");
  }
  pickNodeMainAxisFirst(_point, _requireCategoryAxis) {
    throw new Error("AG Charts - Series.pickNodeMainAxisFirst() not implemented");
  }
  fireNodeClickEvent(event, datum) {
    this.fireEvent(new this.NodeClickEvent("nodeClick", event, datum, this));
  }
  fireNodeDoubleClickEvent(event, datum) {
    this.fireEvent(new this.NodeClickEvent("nodeDoubleClick", event, datum, this));
  }
  toggleSeriesItem(itemId, enabled) {
    this.visible = enabled;
    this.nodeDataRefresh = true;
    this.dispatch("visibility-changed", { itemId, enabled });
  }
  isEnabled() {
    return this.visible;
  }
  getModuleMap() {
    return this.moduleMap;
  }
  createModuleContext() {
    return __spreadProps(__spreadValues({}, this.ctx), { series: this });
  }
  getLabelText(label, params, defaultFormatter = String) {
    var _a;
    if (label.formatter) {
      return (_a = this.ctx.callbackCache.call(label.formatter, __spreadValues({ seriesId: this.id }, params))) != null ? _a : defaultFormatter(params.value);
    }
    return defaultFormatter(params.value);
  }
  getMarkerStyle(marker, params, defaultStyle = marker.getStyle()) {
    var _a, _b;
    const defaultSize = { size: (_b = (_a = params.datum.point) == null ? void 0 : _a.size) != null ? _b : 0 };
    const markerStyle = mergeDefaults(defaultSize, defaultStyle);
    if (marker.formatter) {
      const style = this.ctx.callbackCache.call(marker.formatter, __spreadProps(__spreadValues(__spreadValues({
        seriesId: this.id
      }, markerStyle), params), {
        datum: params.datum.datum
      }));
      return mergeDefaults(style, markerStyle);
    }
    return markerStyle;
  }
  updateMarkerStyle(markerNode, marker, params, defaultStyle = marker.getStyle(), { applyTranslation = true } = {}) {
    const { point } = params.datum;
    const activeStyle = this.getMarkerStyle(marker, params, defaultStyle);
    const visible = this.visible && activeStyle.size > 0 && point && !isNaN(point.x) && !isNaN(point.y);
    if (applyTranslation) {
      markerNode.setProperties(__spreadProps(__spreadValues({ visible }, activeStyle), { translationX: point == null ? void 0 : point.x, translationY: point == null ? void 0 : point.y }));
    } else {
      markerNode.setProperties(__spreadValues({ visible }, activeStyle));
    }
    if (typeof marker.shape === "function" && !markerNode.dirtyPath) {
      markerNode.path.clear({ trackChanges: true });
      markerNode.updatePath();
      markerNode.checkPathDirty();
    }
  }
  getMinRect() {
    return void 0;
  }
  get nodeDataDependencies() {
    var _a;
    return (_a = this._nodeDataDependencies) != null ? _a : { seriesRectWidth: NaN, seriesRectHeight: NaN };
  }
  checkResize(newSeriesRect) {
    const { width: seriesRectWidth, height: seriesRectHeight } = newSeriesRect != null ? newSeriesRect : { width: NaN, height: NaN };
    const newNodeDataDependencies = newSeriesRect ? { seriesRectWidth, seriesRectHeight } : void 0;
    const resize = jsonDiff(this.nodeDataDependencies, newNodeDataDependencies) != null;
    if (resize) {
      this._nodeDataDependencies = newNodeDataDependencies;
      this.markNodeDataDirty();
    }
    return resize;
  }
};
Series.highlightedZIndex = 1e12;
__decorateClass([
  ActionOnSet({
    changeValue: function(newVal, oldVal) {
      this.onSeriesGroupingChange(oldVal, newVal);
    }
  })
], Series.prototype, "seriesGrouping", 2);
var SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION = 30;
var SeriesLayerManager = class {
  constructor(rootGroup) {
    this.groups = {};
    this.series = {};
    this.expectedSeriesCount = 1;
    this.mode = "normal";
    this.rootGroup = rootGroup;
  }
  setSeriesCount(count2) {
    this.expectedSeriesCount = count2;
  }
  requestGroup(seriesConfig) {
    var _a, _b, _c, _d;
    const {
      internalId,
      type,
      rootGroup: seriesRootGroup,
      highlightGroup: seriesHighlightGroup,
      annotationGroup: seriesAnnotationGroup,
      seriesGrouping
    } = seriesConfig;
    const { groupIndex = internalId } = seriesGrouping != null ? seriesGrouping : {};
    if (this.series[internalId] != null) {
      throw new Error(`AG Charts - series already has an allocated layer: ${this.series[internalId]}`);
    }
    if (Object.keys(this.series).length === 0) {
      this.mode = this.expectedSeriesCount >= SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION ? "aggressive-grouping" : "normal";
    }
    (_b = (_a = this.groups)[type]) != null ? _b : _a[type] = {};
    const lookupIndex = this.lookupIdx(groupIndex);
    let groupInfo = this.groups[type][lookupIndex];
    if (!groupInfo) {
      groupInfo = (_d = (_c = this.groups[type])[lookupIndex]) != null ? _d : _c[lookupIndex] = {
        seriesIds: [],
        group: this.rootGroup.appendChild(
          new Group({
            name: `${type}-content`,
            layer: true,
            zIndex: 4,
            zIndexSubOrder: seriesConfig.getGroupZIndexSubOrder("data")
          })
        ),
        highlight: this.rootGroup.appendChild(
          new Group({
            name: `${type}-highlight`,
            layer: true,
            zIndex: 4,
            zIndexSubOrder: seriesConfig.getGroupZIndexSubOrder("highlight")
          })
        ),
        annotation: this.rootGroup.appendChild(
          new Group({
            name: `${type}-annotation`,
            layer: true,
            zIndex: 4,
            zIndexSubOrder: seriesConfig.getGroupZIndexSubOrder("annotation")
          })
        )
      };
    }
    this.series[internalId] = { layerState: groupInfo, seriesConfig };
    groupInfo.seriesIds.push(internalId);
    groupInfo.group.appendChild(seriesRootGroup);
    groupInfo.highlight.appendChild(seriesHighlightGroup);
    groupInfo.annotation.appendChild(seriesAnnotationGroup);
    return groupInfo.group;
  }
  changeGroup(seriesConfig) {
    var _a, _b;
    const { internalId, seriesGrouping, type, rootGroup, highlightGroup, annotationGroup, oldGrouping } = seriesConfig;
    const { groupIndex = internalId } = seriesGrouping != null ? seriesGrouping : {};
    if ((_b = (_a = this.groups[type]) == null ? void 0 : _a[groupIndex]) == null ? void 0 : _b.seriesIds.includes(internalId)) {
      return;
    }
    if (this.series[internalId] != null) {
      this.releaseGroup({
        internalId,
        seriesGrouping: oldGrouping,
        type,
        rootGroup,
        highlightGroup,
        annotationGroup
      });
    }
    this.requestGroup(seriesConfig);
  }
  releaseGroup(seriesConfig) {
    var _a, _b, _c, _d, _e;
    const { internalId, seriesGrouping, rootGroup, highlightGroup, annotationGroup, type } = seriesConfig;
    const { groupIndex = internalId } = seriesGrouping != null ? seriesGrouping : {};
    if (this.series[internalId] == null) {
      throw new Error(`AG Charts - series doesn't have an allocated layer: ${internalId}`);
    }
    const lookupIndex = this.lookupIdx(groupIndex);
    const groupInfo = (_c = (_a = this.groups[type]) == null ? void 0 : _a[lookupIndex]) != null ? _c : (_b = this.series[internalId]) == null ? void 0 : _b.layerState;
    if (groupInfo) {
      groupInfo.seriesIds = groupInfo.seriesIds.filter((v) => v !== internalId);
      groupInfo.group.removeChild(rootGroup);
      groupInfo.highlight.removeChild(highlightGroup);
      groupInfo.annotation.removeChild(annotationGroup);
    }
    if ((groupInfo == null ? void 0 : groupInfo.seriesIds.length) === 0) {
      this.rootGroup.removeChild(groupInfo.group);
      this.rootGroup.removeChild(groupInfo.highlight);
      this.rootGroup.removeChild(groupInfo.annotation);
      delete this.groups[type][lookupIndex];
      delete this.groups[type][internalId];
    } else if ((groupInfo == null ? void 0 : groupInfo.seriesIds.length) > 0) {
      const leadSeriesConfig = (_e = this.series[(_d = groupInfo == null ? void 0 : groupInfo.seriesIds) == null ? void 0 : _d[0]]) == null ? void 0 : _e.seriesConfig;
      groupInfo.group.zIndexSubOrder = leadSeriesConfig == null ? void 0 : leadSeriesConfig.getGroupZIndexSubOrder("data");
      groupInfo.highlight.zIndexSubOrder = leadSeriesConfig == null ? void 0 : leadSeriesConfig.getGroupZIndexSubOrder("highlight");
      groupInfo.annotation.zIndexSubOrder = leadSeriesConfig == null ? void 0 : leadSeriesConfig.getGroupZIndexSubOrder("annotation");
    }
    delete this.series[internalId];
  }
  lookupIdx(groupIndex) {
    if (this.mode === "normal") {
      return groupIndex;
    }
    if (typeof groupIndex === "string") {
      groupIndex = Number(groupIndex.split("-").slice(-1)[0]);
      if (!groupIndex)
        return 0;
    }
    return Math.floor(
      Math.max(Math.min(groupIndex / this.expectedSeriesCount, 1), 0) * SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION
    );
  }
  destroy() {
    for (const groups of Object.values(this.groups)) {
      for (const groupInfo of Object.values(groups)) {
        this.rootGroup.removeChild(groupInfo.group);
        this.rootGroup.removeChild(groupInfo.highlight);
        this.rootGroup.removeChild(groupInfo.annotation);
      }
    }
    this.groups = {};
    this.series = {};
  }
};
var SeriesStateManager = class {
  constructor() {
    this.groups = {};
  }
  registerSeries({
    id,
    seriesGrouping,
    visible,
    type
  }) {
    var _a, _b;
    if (!seriesGrouping)
      return;
    (_b = (_a = this.groups)[type]) != null ? _b : _a[type] = {};
    this.groups[type][id] = { grouping: seriesGrouping, visible };
  }
  deregisterSeries({ id, type }) {
    if (this.groups[type]) {
      delete this.groups[type][id];
    }
    if (this.groups[type] && Object.keys(this.groups[type]).length === 0) {
      delete this.groups[type];
    }
  }
  getVisiblePeerGroupIndex({ type, seriesGrouping }) {
    var _a;
    if (!seriesGrouping)
      return { visibleGroupCount: 1, index: 0 };
    const visibleGroups = [
      ...Object.entries((_a = this.groups[type]) != null ? _a : {}).filter(([_, entry]) => entry.visible).reduce((result, [_, next]) => {
        if (next.visible) {
          result.add(next.grouping.groupIndex);
        }
        return result;
      }, /* @__PURE__ */ new Set()).values()
    ];
    visibleGroups.sort((a, b) => a - b);
    return {
      visibleGroupCount: visibleGroups.length,
      index: visibleGroups.indexOf(seriesGrouping.groupIndex)
    };
  }
};
var BaseLayoutProcessor = class {
  constructor(chartLike, layoutService) {
    this.chartLike = chartLike;
    this.layoutService = layoutService;
    this.destroyFns = [];
    this.destroyFns.push(
      // eslint-disable-next-line sonarjs/no-duplicate-string
      this.layoutService.addListener("layout-complete", (e) => this.layoutComplete(e)),
      this.layoutService.addListener("start-layout", (e) => this.positionPadding(e.shrinkRect)),
      this.layoutService.addListener("start-layout", (e) => this.positionCaptions(e.shrinkRect))
    );
  }
  destroy() {
    this.destroyFns.forEach((cb) => cb());
  }
  layoutComplete({ clipSeries, series: { paddedRect } }) {
    const { seriesArea, seriesRoot } = this.chartLike;
    if (seriesArea.clip || clipSeries) {
      seriesRoot.setClipRectInGroupCoordinateSpace(paddedRect);
    } else {
      seriesRoot.setClipRectInGroupCoordinateSpace();
    }
  }
  positionPadding(shrinkRect) {
    const { padding } = this.chartLike;
    shrinkRect.shrink(padding.left, "left");
    shrinkRect.shrink(padding.top, "top");
    shrinkRect.shrink(padding.right, "right");
    shrinkRect.shrink(padding.bottom, "bottom");
    return { shrinkRect };
  }
  positionCaptions(shrinkRect) {
    var _a, _b, _c, _d;
    const { title, subtitle, footnote } = this.chartLike;
    const newShrinkRect = shrinkRect.clone();
    const updateCaption = (caption) => {
      var _a2;
      const defaultCaptionHeight = shrinkRect.height / 10;
      const captionLineHeight = (_a2 = caption.lineHeight) != null ? _a2 : caption.fontSize * Text.defaultLineHeightRatio;
      const maxWidth = shrinkRect.width;
      const maxHeight = Math.max(captionLineHeight, defaultCaptionHeight);
      caption.computeTextWrap(maxWidth, maxHeight);
    };
    const computeX = (align) => {
      if (align === "left") {
        return newShrinkRect.x;
      } else if (align === "right") {
        return newShrinkRect.x + newShrinkRect.width;
      } else if (align !== "center") {
        Logger.error(`invalid textAlign value: ${align}`);
      }
      return newShrinkRect.x + newShrinkRect.width / 2;
    };
    const positionTopAndShrinkBBox = (caption, spacing) => {
      const baseY = newShrinkRect.y;
      caption.node.x = computeX(caption.textAlign);
      caption.node.y = baseY;
      caption.node.textBaseline = "top";
      updateCaption(caption);
      const bbox = caption.node.computeBBox();
      const bboxHeight = Math.ceil(bbox.y - baseY + bbox.height + spacing);
      newShrinkRect.shrink(bboxHeight, "top");
    };
    const positionBottomAndShrinkBBox = (caption, spacing) => {
      const baseY = newShrinkRect.y + newShrinkRect.height;
      caption.node.x = computeX(caption.textAlign);
      caption.node.y = baseY;
      caption.node.textBaseline = "bottom";
      updateCaption(caption);
      const bbox = caption.node.computeBBox();
      const bboxHeight = Math.ceil(baseY - bbox.y + spacing);
      newShrinkRect.shrink(bboxHeight, "bottom");
    };
    if (subtitle) {
      subtitle.node.visible = (_a = subtitle.enabled) != null ? _a : false;
    }
    if (title) {
      title.node.visible = title.enabled;
      if (title.node.visible) {
        const defaultTitleSpacing = (subtitle == null ? void 0 : subtitle.node.visible) ? Caption.SMALL_PADDING : Caption.LARGE_PADDING;
        const spacing = (_b = title.spacing) != null ? _b : defaultTitleSpacing;
        positionTopAndShrinkBBox(title, spacing);
      }
    }
    if (subtitle && subtitle.node.visible) {
      positionTopAndShrinkBBox(subtitle, (_c = subtitle.spacing) != null ? _c : 0);
    }
    if (footnote) {
      footnote.node.visible = footnote.enabled;
      if (footnote.node.visible) {
        positionBottomAndShrinkBBox(footnote, (_d = footnote.spacing) != null ? _d : 0);
      }
    }
    return { shrinkRect: newShrinkRect };
  }
};
var UpdateService = class extends Listeners {
  constructor(updateCallback) {
    super();
    this.updateCallback = updateCallback;
  }
  update(type = 0, { forceNodeDataRefresh = false, skipAnimations = false } = {}) {
    this.updateCallback(type, { forceNodeDataRefresh, skipAnimations });
  }
  dispatchUpdateComplete(minRect) {
    const event = { type: "update-complete", minRect };
    this.dispatch("update-complete", event);
  }
};
function initialiseSpecialOverrides(opts) {
  let globalWindow;
  if (opts.window != null) {
    globalWindow = opts.window;
  } else if (typeof window !== "undefined") {
    globalWindow = window;
  } else if (typeof global !== "undefined") {
    globalWindow = global.window;
  } else {
    throw new Error("AG Charts - unable to resolve global window");
  }
  let globalDocument;
  if (opts.document != null) {
    globalDocument = opts.document;
  } else if (typeof document !== "undefined") {
    globalDocument = document;
  } else if (typeof global !== "undefined") {
    globalDocument = global.document;
  } else {
    throw new Error("AG Charts - unable to resolve global document");
  }
  return {
    document: globalDocument,
    window: globalWindow,
    overrideDevicePixelRatio: opts.overrideDevicePixelRatio,
    sceneMode: opts.sceneMode
  };
}
var SeriesArea = class {
  constructor() {
    this.clip = void 0;
    this.padding = new Padding(0);
  }
};
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], SeriesArea.prototype, "clip", 2);
var chartsInstances = /* @__PURE__ */ new WeakMap();
var Chart = class extends Observable {
  constructor(specialOverrides, resources) {
    var _a;
    super();
    this.id = createId(this);
    this.processedOptions = {};
    this.userOptions = {};
    this.queuedUserOptions = [];
    this.seriesRoot = new Group({ name: `${this.id}-Series-root` });
    this.debug = Debug.create();
    this.extraDebugStats = {};
    this.container = void 0;
    this.data = [];
    this._firstAutoSize = true;
    this.padding = new Padding(20);
    this._seriesArea = new SeriesArea();
    this.title = void 0;
    this.subtitle = void 0;
    this.footnote = void 0;
    this.mode = "standalone";
    this._destroyed = false;
    this._destroyFns = [];
    this.modules = /* @__PURE__ */ new Map();
    this.legends = /* @__PURE__ */ new Map();
    this.processors = [];
    this._pendingFactoryUpdatesCount = 0;
    this._performUpdateNoRenderCount = 0;
    this._performUpdateType = 6;
    this._performUpdateSkipAnimations = false;
    this.updateShortcutCount = 0;
    this.seriesToUpdate = /* @__PURE__ */ new Set();
    this.updateMutex = new Mutex();
    this.updateRequestors = {};
    this.performUpdateTrigger = debouncedCallback((_0) => __async(this, [_0], function* ({ count: count2 }) {
      if (this._destroyed)
        return;
      this.updateMutex.acquire(() => __async(this, null, function* () {
        try {
          yield this.performUpdate(count2);
        } catch (error) {
          this._lastPerformUpdateError = error;
          Logger.error("update error", error);
        }
      }));
    }));
    this._axes = [];
    this._series = [];
    this.lastInteractionEvent = void 0;
    this.pointerScheduler = debouncedAnimationFrame(() => {
      if (this.lastInteractionEvent) {
        this.handlePointer(this.lastInteractionEvent);
      }
      this.lastInteractionEvent = void 0;
    });
    this.onSeriesNodeClick = (event) => {
      const seriesNodeClickEvent = __spreadProps(__spreadValues({}, event), {
        type: "seriesNodeClick"
      });
      Object.defineProperty(seriesNodeClickEvent, "series", {
        enumerable: false,
        // Should display the deprecation warning
        get: () => event.series
      });
      this.fireEvent(seriesNodeClickEvent);
    };
    this.onSeriesNodeDoubleClick = (event) => {
      const seriesNodeDoubleClick = __spreadProps(__spreadValues({}, event), {
        type: "seriesNodeDoubleClick"
      });
      this.fireEvent(seriesNodeDoubleClick);
    };
    this.specialOverrides = initialiseSpecialOverrides(specialOverrides);
    const { window: window2, document: document2 } = this.specialOverrides;
    const scene = resources == null ? void 0 : resources.scene;
    const element2 = (_a = resources == null ? void 0 : resources.element) != null ? _a : document2.createElement("div");
    const container = resources == null ? void 0 : resources.container;
    const root = new Group({ name: "root" });
    root.visible = false;
    root.append(this.seriesRoot);
    this.axisGridGroup = new Group({
      name: "Axes-Grids",
      layer: true,
      zIndex: 1
      /* AXIS_GRID_ZINDEX */
    });
    root.appendChild(this.axisGridGroup);
    this.axisGroup = new Group({
      name: "Axes",
      layer: true,
      zIndex: 2
      /* AXIS_ZINDEX */
    });
    root.appendChild(this.axisGroup);
    this.element = element2;
    element2.classList.add("ag-chart-wrapper");
    element2.style.position = "relative";
    this.scene = scene != null ? scene : new Scene(this.specialOverrides);
    this.scene.root = root;
    this.scene.container = element2;
    this.autoSize = true;
    this.chartEventManager = new ChartEventManager();
    this.cursorManager = new CursorManager(element2);
    this.highlightManager = new HighlightManager();
    this.interactionManager = new InteractionManager(element2, document2, window2);
    this.zoomManager = new ZoomManager();
    this.layoutService = new LayoutService();
    this.updateService = new UpdateService(
      (type = 0, { forceNodeDataRefresh, skipAnimations }) => this.update(type, { forceNodeDataRefresh, skipAnimations })
    );
    this.seriesStateManager = new SeriesStateManager();
    this.seriesLayerManager = new SeriesLayerManager(this.seriesRoot);
    this.callbackCache = new CallbackCache();
    this.animationManager = new AnimationManager(this.interactionManager, this.updateMutex);
    this.animationManager.skip();
    this.animationManager.play();
    this.processors = [new BaseLayoutProcessor(this, this.layoutService)];
    this.tooltip = new Tooltip(this.scene.canvas.element, document2, window2, document2.body);
    this.tooltipManager = new TooltipManager(this.tooltip, this.interactionManager);
    this.overlays = new ChartOverlays(this.element);
    this.highlight = new ChartHighlight();
    this.container = container;
    SizeMonitor.observe(this.element, (size) => this.rawResize(size));
    this._destroyFns.push(
      this.interactionManager.addListener("click", (event) => this.onClick(event)),
      this.interactionManager.addListener("dblclick", (event) => this.onDoubleClick(event)),
      this.interactionManager.addListener("hover", (event) => this.onMouseMove(event)),
      this.interactionManager.addListener("leave", (event) => this.onLeave(event)),
      this.interactionManager.addListener("page-left", () => this.destroy()),
      this.interactionManager.addListener("wheel", () => this.disablePointer()),
      // Block redundant and interfering attempts to update the hovered element during dragging.
      this.interactionManager.addListener("drag-start", () => this.disablePointer()),
      this.animationManager.addListener("animation-frame", (_) => {
        this.update(
          5
          /* SCENE_RENDER */
        );
      }),
      this.highlightManager.addListener("highlight-change", (event) => this.changeHighlightDatum(event)),
      this.zoomManager.addListener(
        "zoom-change",
        (_) => this.update(1, { forceNodeDataRefresh: true, skipAnimations: true })
      )
    );
    this.attachLegend("category", Legend);
    this.legend = this.legends.get("category");
  }
  static getInstance(element2) {
    return chartsInstances.get(element2);
  }
  getOptions() {
    var _a;
    const { queuedUserOptions } = this;
    const lastUpdateOptions = (_a = queuedUserOptions[queuedUserOptions.length - 1]) != null ? _a : this.userOptions;
    return jsonClone(lastUpdateOptions);
  }
  autoSizeChanged(value) {
    const { style } = this.element;
    if (value) {
      style.display = "block";
      style.width = "100%";
      style.height = "100%";
      if (!this._lastAutoSize) {
        return;
      }
      this.resize(void 0, void 0, "autoSize option");
    } else {
      style.display = "inline-block";
      style.width = "auto";
      style.height = "auto";
    }
  }
  download(fileName, fileFormat) {
    this.scene.download(fileName, fileFormat);
  }
  get seriesArea() {
    return this._seriesArea;
  }
  set seriesArea(newArea) {
    if (!newArea) {
      this._seriesArea = new SeriesArea();
    } else {
      this._seriesArea = newArea;
    }
  }
  get destroyed() {
    return this._destroyed;
  }
  addModule(module2) {
    if (this.modules.has(module2.optionsKey)) {
      throw new Error(`AG Charts - module already initialised: ${module2.optionsKey}`);
    }
    const moduleInstance = new module2.instanceConstructor(this.getModuleContext());
    if (module2.type === "legend") {
      const legend = moduleInstance;
      this.legends.set(module2.identifier, legend);
      legend.attachLegend(this.scene.root);
    }
    this.modules.set(module2.optionsKey, moduleInstance);
  }
  removeModule(module2) {
    var _a;
    if (module2.type === "legend") {
      this.legends.delete(module2.identifier);
    }
    (_a = this.modules.get(module2.optionsKey)) == null ? void 0 : _a.destroy();
    this.modules.delete(module2.optionsKey);
  }
  attachLegend(legendType, legendConstructor) {
    const legend = new legendConstructor(this.getModuleContext());
    this.legends.set(legendType, legend);
    legend.attachLegend(this.scene.root);
  }
  isModuleEnabled(module2) {
    return this.modules.has(module2.optionsKey);
  }
  getModuleContext() {
    const {
      scene,
      animationManager,
      chartEventManager,
      cursorManager,
      highlightManager,
      interactionManager,
      tooltipManager,
      zoomManager,
      layoutService,
      updateService,
      seriesStateManager,
      seriesLayerManager,
      callbackCache,
      specialOverrides: { window: window2, document: document2 }
    } = this;
    return {
      window: window2,
      document: document2,
      scene,
      animationManager,
      chartEventManager,
      cursorManager,
      highlightManager,
      interactionManager,
      tooltipManager,
      zoomManager,
      chartService: this,
      layoutService,
      updateService,
      seriesStateManager,
      seriesLayerManager,
      callbackCache
    };
  }
  destroy(opts) {
    if (this._destroyed) {
      return;
    }
    const keepTransferableResources = opts == null ? void 0 : opts.keepTransferableResources;
    let result;
    this._performUpdateType = 6;
    this._destroyFns.forEach((fn) => fn());
    this.processors.forEach((p) => p.destroy());
    this.tooltipManager.destroy();
    this.tooltip.destroy();
    this.legends.forEach((legend) => legend.destroy());
    this.legends.clear();
    this.overlays.destroy();
    SizeMonitor.unobserve(this.element);
    for (const { instance: moduleInstance } of Object.values(this.modules)) {
      this.removeModule(moduleInstance);
    }
    this.interactionManager.destroy();
    this.animationManager.stop();
    if (keepTransferableResources) {
      this.scene.strip();
      result = { container: this.container, scene: this.scene, element: this.element };
    } else {
      this.scene.destroy();
      this.container = void 0;
    }
    this.removeAllSeries();
    this.seriesLayerManager.destroy();
    this.axes.forEach((a) => a.destroy());
    this.axes = [];
    this.callbackCache.invalidateCache();
    this._destroyed = true;
    return result;
  }
  disablePointer(highlightOnly = false) {
    if (!highlightOnly) {
      this.tooltipManager.removeTooltip(this.id);
    }
    this.highlightManager.updateHighlight(this.id);
    if (this.lastInteractionEvent) {
      this.lastInteractionEvent = void 0;
    }
  }
  requestFactoryUpdate(cb) {
    this._pendingFactoryUpdatesCount++;
    this.updateMutex.acquire(() => __async(this, null, function* () {
      yield cb();
      this._pendingFactoryUpdatesCount--;
    }));
  }
  get performUpdateType() {
    return this._performUpdateType;
  }
  get lastPerformUpdateError() {
    return this._lastPerformUpdateError;
  }
  update(type = 0, opts) {
    var _a, _b;
    const {
      forceNodeDataRefresh = false,
      skipAnimations,
      seriesToUpdate = this.series,
      newAnimationBatch
    } = opts != null ? opts : {};
    if (forceNodeDataRefresh) {
      this.series.forEach((series) => series.markNodeDataDirty());
    }
    for (const series of seriesToUpdate) {
      this.seriesToUpdate.add(series);
    }
    if (skipAnimations) {
      this.animationManager.skipCurrentBatch();
      this._performUpdateSkipAnimations = true;
    }
    if (newAnimationBatch) {
      if (this.animationManager.isActive()) {
        this._performUpdateSkipAnimations = true;
      } else {
        (_a = this._performUpdateSkipAnimations) != null ? _a : this._performUpdateSkipAnimations = false;
      }
    }
    if (Debug.check(true)) {
      let stack = (_b = new Error().stack) != null ? _b : "<unknown>";
      stack = stack.replace(/\([^)]*/g, "");
      this.updateRequestors[stack] = type;
    }
    if (type < this._performUpdateType) {
      this._performUpdateType = type;
      this.performUpdateTrigger.schedule(opts == null ? void 0 : opts.backOffMs);
    }
  }
  performUpdate(count2) {
    return __async(this, null, function* () {
      var _a;
      const { _performUpdateType: performUpdateType, extraDebugStats } = this;
      const seriesToUpdate = [...this.seriesToUpdate];
      this._performUpdateType = 6;
      this.seriesToUpdate.clear();
      if (this.updateShortcutCount === 0 && performUpdateType < 5) {
        this.animationManager.startBatch(this._performUpdateSkipAnimations);
      }
      this.debug("Chart.performUpdate() - start", ChartUpdateType[performUpdateType]);
      const splits = { start: performance.now() };
      switch (performUpdateType) {
        case 0:
        case 1:
          yield this.processData();
          this.disablePointer(true);
          splits["\u{1F3ED}"] = performance.now();
        case 2:
          if (this.checkUpdateShortcut(
            2
            /* PERFORM_LAYOUT */
          ))
            break;
          if (!this.checkFirstAutoSize(seriesToUpdate))
            break;
          yield this.processLayout();
          splits["\u2316"] = performance.now();
        case 3:
          if (this.checkUpdateShortcut(
            3
            /* SERIES_UPDATE */
          ))
            break;
          const { seriesRect } = this;
          const seriesUpdates = [...seriesToUpdate].map((series) => series.update({ seriesRect }));
          yield Promise.all(seriesUpdates);
          splits["\u{1F914}"] = performance.now();
        case 4:
          if (this.checkUpdateShortcut(
            4
            /* TOOLTIP_RECALCULATION */
          ))
            break;
          const tooltipMeta = this.tooltipManager.getTooltipMeta(this.id);
          const isHovered = ((_a = tooltipMeta == null ? void 0 : tooltipMeta.event) == null ? void 0 : _a.type) === "hover";
          if (performUpdateType <= 3 && isHovered) {
            this.handlePointer(tooltipMeta.event);
          }
          splits["\u2196"] = performance.now();
        case 5:
          if (this.checkUpdateShortcut(
            5
            /* SCENE_RENDER */
          ))
            break;
          extraDebugStats["updateShortcutCount"] = this.updateShortcutCount;
          yield this.scene.render({ debugSplitTimes: splits, extraDebugStats });
          this.extraDebugStats = {};
        case 6:
          this.updateShortcutCount = 0;
          this.updateRequestors = {};
          this._performUpdateSkipAnimations = void 0;
          this.animationManager.endBatch();
      }
      this.updateService.dispatchUpdateComplete(this.getMinRect());
      const end = performance.now();
      this.debug("Chart.performUpdate() - end", {
        chart: this,
        durationMs: Math.round((end - splits["start"]) * 100) / 100,
        count: count2,
        performUpdateType: ChartUpdateType[performUpdateType]
      });
    });
  }
  checkUpdateShortcut(checkUpdateType) {
    const maxShortcuts = 3;
    if (this.updateShortcutCount > maxShortcuts) {
      Logger.warn(
        `exceeded the maximum number of simultaneous updates (${maxShortcuts + 1}), discarding changes and rendering`,
        this.updateRequestors
      );
      return false;
    }
    if (this.performUpdateType <= checkUpdateType) {
      this.updateShortcutCount++;
      return true;
    }
    return false;
  }
  checkFirstAutoSize(seriesToUpdate) {
    if (this.autoSize && !this._lastAutoSize) {
      const count2 = this._performUpdateNoRenderCount++;
      const backOffMs = (count2 ^ 2) * 10;
      if (count2 < 8) {
        this.update(2, { seriesToUpdate, backOffMs });
        this.debug("Chart.checkFirstAutoSize() - backing off until first size update", backOffMs);
        return false;
      }
      this.debug("Chart.checkFirstAutoSize() - timeout for first size update.");
    }
    this._performUpdateNoRenderCount = 0;
    return true;
  }
  set axes(values) {
    const removedAxes = /* @__PURE__ */ new Set();
    this._axes.forEach((axis) => {
      axis.detachAxis(this.axisGroup, this.axisGridGroup);
      removedAxes.add(axis);
    });
    this._axes = values.filter((a) => !a.linkedTo).concat(values.filter((a) => a.linkedTo));
    this._axes.forEach((axis) => {
      axis.attachAxis(this.axisGroup, this.axisGridGroup);
      removedAxes.delete(axis);
    });
    this.zoomManager.updateAxes(this._axes);
    removedAxes.forEach((axis) => axis.destroy());
  }
  get axes() {
    return this._axes;
  }
  set series(values) {
    this.removeAllSeries();
    this.seriesLayerManager.setSeriesCount(values.length);
    values.forEach((series) => this.addSeries(series));
  }
  get series() {
    return this._series;
  }
  addSeries(series) {
    const { series: allSeries } = this;
    const canAdd = allSeries.indexOf(series) < 0;
    if (canAdd) {
      allSeries.push(series);
      if (series.rootGroup.parent == null) {
        this.seriesLayerManager.requestGroup(series);
      }
      this.initSeries(series);
      return true;
    }
    return false;
  }
  initSeries(series) {
    const chart = this;
    series.chart = {
      get mode() {
        return chart.mode;
      },
      get seriesRect() {
        return chart.seriesRect;
      },
      placeLabels() {
        return chart.placeLabels();
      }
    };
    series.setChartData(this.data);
    this.addSeriesListeners(series);
    series.addChartEventListeners();
  }
  removeAllSeries() {
    this.series.forEach((series) => {
      series.removeEventListener("nodeClick", this.onSeriesNodeClick);
      series.removeEventListener("nodeDoubleClick", this.onSeriesNodeDoubleClick);
      series.destroy();
      series.chart = void 0;
    });
    this._series = [];
  }
  addSeriesListeners(series) {
    if (this.hasEventListener("seriesNodeClick")) {
      series.addEventListener("nodeClick", this.onSeriesNodeClick);
    }
    if (this.hasEventListener("seriesNodeDoubleClick")) {
      series.addEventListener("nodeDoubleClick", this.onSeriesNodeDoubleClick);
    }
  }
  updateAllSeriesListeners() {
    this.series.forEach((series) => {
      series.removeEventListener("nodeClick", this.onSeriesNodeClick);
      series.removeEventListener("nodeDoubleClick", this.onSeriesNodeDoubleClick);
      this.addSeriesListeners(series);
    });
  }
  assignSeriesToAxes() {
    this.axes.forEach((axis) => {
      axis.boundSeries = this.series.filter((s) => {
        const seriesAxis = s.axes[axis.direction];
        return seriesAxis === axis;
      });
    });
  }
  assignAxesToSeries() {
    const directionToAxesMap = {};
    this.axes.forEach((axis) => {
      var _a;
      const direction = axis.direction;
      const directionAxes = (_a = directionToAxesMap[direction]) != null ? _a : directionToAxesMap[direction] = [];
      directionAxes.push(axis);
    });
    this.series.forEach((series) => {
      series.directions.forEach((direction) => {
        const directionAxes = directionToAxesMap[direction];
        if (!directionAxes) {
          Logger.warnOnce(
            `no available axis for direction [${direction}]; check series and axes configuration.`
          );
          return;
        }
        const seriesKeys = series.getKeys(direction);
        const newAxis = this.findMatchingAxis(directionAxes, seriesKeys);
        if (!newAxis) {
          Logger.warnOnce(
            `no matching axis for direction [${direction}] and keys [${seriesKeys}]; check series and axes configuration.`
          );
          return;
        }
        series.axes[direction] = newAxis;
      });
    });
  }
  findMatchingAxis(directionAxes, directionKeys) {
    for (const axis of directionAxes) {
      const axisKeys = axis.keys;
      if (!axisKeys.length) {
        return axis;
      }
      if (!directionKeys) {
        continue;
      }
      for (const directionKey of directionKeys) {
        if (axisKeys.indexOf(directionKey) >= 0) {
          return axis;
        }
      }
    }
  }
  rawResize(size) {
    var _a;
    let { width, height } = size;
    width = Math.floor(width);
    height = Math.floor(height);
    if (!this.autoSize) {
      return;
    }
    if (width === 0 && height === 0) {
      return;
    }
    const [autoWidth = 0, authHeight = 0] = (_a = this._lastAutoSize) != null ? _a : [];
    if (autoWidth === width && authHeight === height) {
      return;
    }
    this._lastAutoSize = [width, height];
    this.resize(void 0, void 0, "SizeMonitor");
  }
  resize(width, height, source) {
    var _a, _b, _c, _d;
    width != null ? width : width = (_b = this.width) != null ? _b : this.autoSize ? (_a = this._lastAutoSize) == null ? void 0 : _a[0] : this.scene.canvas.width;
    height != null ? height : height = (_d = this.height) != null ? _d : this.autoSize ? (_c = this._lastAutoSize) == null ? void 0 : _c[1] : this.scene.canvas.height;
    this.debug(`Chart.resize() from ${source}`, { width, height, stack: new Error().stack });
    if (!width || !height || !Number.isFinite(width) || !Number.isFinite(height))
      return;
    if (this.scene.resize(width, height)) {
      this.disablePointer();
      this.animationManager.reset();
      let skipAnimations = true;
      if (this.autoSize && this._firstAutoSize) {
        skipAnimations = false;
        this._firstAutoSize = false;
      }
      this.update(2, { forceNodeDataRefresh: true, skipAnimations });
    }
  }
  processData() {
    return __async(this, null, function* () {
      if (this.series.some((s) => s.canHaveAxes)) {
        this.assignAxesToSeries();
        this.assignSeriesToAxes();
      }
      const dataController = new DataController(this.mode);
      const seriesPromises = this.series.map((s) => s.processData(dataController));
      yield dataController.execute();
      yield Promise.all(seriesPromises);
      yield this.updateLegend();
    });
  }
  placeLabels() {
    const visibleSeries = [];
    const data = [];
    for (const series of this.series) {
      if (!series.visible) {
        continue;
      }
      const labelData = series.getLabelData();
      if (!(labelData && isPointLabelDatum(labelData[0]))) {
        continue;
      }
      data.push(labelData);
      visibleSeries.push(series);
    }
    const { seriesRect } = this;
    const { top, right, bottom, left } = this.seriesArea.padding;
    const labels = seriesRect && data.length > 0 ? placeLabels(data, {
      x: -left,
      y: -top,
      width: seriesRect.width + left + right,
      height: seriesRect.height + top + bottom
    }) : [];
    return new Map(labels.map((l, i) => [visibleSeries[i], l]));
  }
  updateLegend() {
    return __async(this, null, function* () {
      this.legends.forEach((legend, legendType) => {
        const isCategoryLegendData = (data) => data.every((d) => d.legendType === "category");
        const legendData = this.series.filter((s) => s.properties.showInLegend).flatMap((s) => s.getLegendData(legendType));
        if (isCategoryLegendData(legendData)) {
          this.validateCategoryLegendData(legendData);
        }
        legend.data = legendData;
      });
    });
  }
  validateCategoryLegendData(legendData) {
    const labelMarkerFills = {};
    legendData.forEach((d) => {
      var _a, _b, _c, _d, _e;
      const seriesType = (_a = this.series.find((s) => s.id === d.seriesId)) == null ? void 0 : _a.type;
      if (!seriesType)
        return;
      (_b = labelMarkerFills[seriesType]) != null ? _b : labelMarkerFills[seriesType] = {};
      (_e = (_c = labelMarkerFills[seriesType])[_d = d.label.text]) != null ? _e : _c[_d] = /* @__PURE__ */ new Set();
      if (d.marker.fill != null) {
        labelMarkerFills[seriesType][d.label.text].add(d.marker.fill);
      }
    });
    for (const seriesMarkers of Object.values(labelMarkerFills)) {
      for (const [name, fills] of Object.entries(seriesMarkers)) {
        if (fills.size > 1) {
          Logger.warnOnce(
            `legend item '${name}' has multiple fill colors, this may cause unexpected behaviour.`
          );
        }
      }
    }
  }
  processLayout() {
    return __async(this, null, function* () {
      var _a;
      const oldRect = this.animationRect;
      yield this.performLayout();
      if (oldRect && !((_a = this.animationRect) == null ? void 0 : _a.equals(oldRect))) {
        this.animationManager.skipCurrentBatch();
      }
      this.handleOverlays();
      this.debug("Chart.performUpdate() - seriesRect", this.seriesRect);
    });
  }
  performLayout() {
    return __async(this, null, function* () {
      if (this.scene.root) {
        this.scene.root.visible = true;
      }
      const { width, height } = this.scene;
      let ctx = { shrinkRect: new BBox(0, 0, width, height) };
      ctx = this.layoutService.dispatchPerformLayout("start-layout", ctx);
      ctx = this.layoutService.dispatchPerformLayout("before-series", ctx);
      return ctx.shrinkRect;
    });
  }
  // x/y are local canvas coordinates in CSS pixels, not actual pixels
  pickSeriesNode(point, exactMatchOnly, maxDistance) {
    var _a, _b;
    const start = performance.now();
    const pickModes = exactMatchOnly ? [
      0
      /* EXACT_SHAPE_MATCH */
    ] : void 0;
    const reverseSeries = [...this.series].reverse();
    let result;
    for (const series of reverseSeries) {
      if (!series.visible || !series.rootGroup.visible) {
        continue;
      }
      const { match, distance } = (_a = series.pickNode(point, pickModes)) != null ? _a : {};
      if (!match || distance == null) {
        continue;
      }
      if ((!result || result.distance > distance) && distance <= (maxDistance != null ? maxDistance : Infinity)) {
        result = { series, distance, datum: match };
      }
      if (distance === 0) {
        break;
      }
    }
    this.extraDebugStats["pickSeriesNode"] = Math.round(
      ((_b = this.extraDebugStats["pickSeriesNode"]) != null ? _b : 0) + (performance.now() - start)
    );
    return result;
  }
  onMouseMove(event) {
    this.lastInteractionEvent = event;
    this.pointerScheduler.schedule();
    this.extraDebugStats["mouseX"] = event.offsetX;
    this.extraDebugStats["mouseY"] = event.offsetY;
    this.update(
      5
      /* SCENE_RENDER */
    );
  }
  onLeave(event) {
    if (this.tooltip.pointerLeftOntoTooltip(event)) {
      return;
    }
    this.disablePointer();
    this.update(
      5
      /* SCENE_RENDER */
    );
  }
  handlePointer(event) {
    const { lastPick, hoverRect } = this;
    const { offsetX, offsetY } = event;
    const disablePointer = (highlightOnly = false) => {
      if (lastPick) {
        this.disablePointer(highlightOnly);
      }
    };
    if (!(hoverRect == null ? void 0 : hoverRect.containsPoint(offsetX, offsetY))) {
      disablePointer();
      return;
    }
    this.handlePointerTooltip(event, disablePointer);
    this.handlePointerNode(event);
  }
  handlePointerTooltip(event, disablePointer) {
    const { lastPick, tooltip } = this;
    const { range: range3 } = tooltip;
    const { offsetX, offsetY } = event;
    let pixelRange;
    if (typeof range3 === "number" && Number.isFinite(range3)) {
      pixelRange = range3;
    }
    const pick = this.pickSeriesNode({ x: offsetX, y: offsetY }, range3 === "exact", pixelRange);
    if (!pick) {
      this.tooltipManager.removeTooltip(this.id);
      if (this.highlight.range === "tooltip")
        disablePointer(true);
      return;
    }
    const isNewDatum = this.highlight.range === "node" || !lastPick || lastPick.datum !== pick.datum;
    let html;
    if (isNewDatum) {
      html = pick.series.getTooltipHtml(pick.datum);
      if (this.highlight.range === "tooltip") {
        this.highlightManager.updateHighlight(this.id, pick.datum);
      }
    } else if (lastPick) {
      lastPick.event = event.sourceEvent;
    }
    const isPixelRange = pixelRange != null;
    const tooltipEnabled = this.tooltip.enabled && pick.series.properties.tooltip.enabled;
    const exactlyMatched = range3 === "exact" && pick.distance === 0;
    const rangeMatched = range3 === "nearest" || isPixelRange || exactlyMatched;
    const shouldUpdateTooltip = tooltipEnabled && rangeMatched && (!isNewDatum || html !== void 0);
    const meta = TooltipManager.makeTooltipMeta(event, this.scene.canvas, pick.datum, this.specialOverrides.window);
    if (shouldUpdateTooltip) {
      this.tooltipManager.updateTooltip(this.id, meta, html);
    }
  }
  handlePointerNode(event) {
    const found = this.checkSeriesNodeRange(event, (series, datum) => {
      if (series.hasEventListener("nodeClick") || series.hasEventListener("nodeDoubleClick")) {
        this.cursorManager.updateCursor("chart", "pointer");
      }
      if (this.highlight.range === "node") {
        this.highlightManager.updateHighlight(this.id, datum);
      }
    });
    if (!found) {
      this.cursorManager.updateCursor("chart");
      if (this.highlight.range === "node") {
        this.highlightManager.updateHighlight(this.id);
      }
    }
  }
  onClick(event) {
    if (this.checkSeriesNodeClick(event)) {
      this.update(
        3
        /* SERIES_UPDATE */
      );
      return;
    }
    this.fireEvent({
      type: "click",
      event: event.sourceEvent
    });
  }
  onDoubleClick(event) {
    if (this.checkSeriesNodeDoubleClick(event)) {
      this.update(
        3
        /* SERIES_UPDATE */
      );
      return;
    }
    this.fireEvent({
      type: "doubleClick",
      event: event.sourceEvent
    });
  }
  checkSeriesNodeClick(event) {
    return this.checkSeriesNodeRange(event, (series, datum) => series.fireNodeClickEvent(event.sourceEvent, datum));
  }
  checkSeriesNodeDoubleClick(event) {
    return this.checkSeriesNodeRange(
      event,
      (series, datum) => series.fireNodeDoubleClickEvent(event.sourceEvent, datum)
    );
  }
  checkSeriesNodeRange(event, callback) {
    const nearestNode = this.pickSeriesNode({ x: event.offsetX, y: event.offsetY }, false);
    const datum = nearestNode == null ? void 0 : nearestNode.datum;
    const nodeClickRange = datum == null ? void 0 : datum.series.properties.nodeClickRange;
    let pixelRange;
    if (typeof nodeClickRange === "number" && Number.isFinite(nodeClickRange)) {
      pixelRange = nodeClickRange;
    }
    let pickedNode = this.pickSeriesNode({ x: event.offsetX, y: event.offsetY }, true);
    if (pickedNode) {
      this.highlightManager.updatePicked(this.id, pickedNode.datum);
    } else {
      this.highlightManager.updatePicked(this.id);
    }
    if (datum && nodeClickRange === "nearest") {
      callback(datum.series, datum);
      return true;
    }
    if (nodeClickRange !== "exact") {
      pickedNode = this.pickSeriesNode({ x: event.offsetX, y: event.offsetY }, false, pixelRange);
    }
    if (!pickedNode)
      return false;
    const isPixelRange = pixelRange != null;
    const exactlyMatched = nodeClickRange === "exact" && pickedNode.distance === 0;
    if (isPixelRange || exactlyMatched) {
      callback(pickedNode.series, pickedNode.datum);
      return true;
    }
    return false;
  }
  changeHighlightDatum(event) {
    var _a, _b;
    const seriesToUpdate = /* @__PURE__ */ new Set();
    const { series: newSeries = void 0, datum: newDatum } = (_a = event.currentHighlight) != null ? _a : {};
    const { series: lastSeries = void 0, datum: lastDatum } = (_b = event.previousHighlight) != null ? _b : {};
    if (lastSeries) {
      seriesToUpdate.add(lastSeries);
    }
    if (newSeries) {
      seriesToUpdate.add(newSeries);
    }
    if ((lastSeries == null ? void 0 : lastSeries.properties.cursor) && lastDatum) {
      this.cursorManager.updateCursor(lastSeries.id);
    }
    if ((newSeries == null ? void 0 : newSeries.properties.cursor) && newDatum) {
      this.cursorManager.updateCursor(newSeries.id, newSeries.properties.cursor);
    }
    this.lastPick = event.currentHighlight ? { datum: event.currentHighlight } : void 0;
    const updateAll = newSeries == null || lastSeries == null;
    if (updateAll) {
      this.update(
        3
        /* SERIES_UPDATE */
      );
    } else {
      this.update(3, { seriesToUpdate });
    }
  }
  waitForUpdate(timeoutMs = 5e3) {
    return __async(this, null, function* () {
      const start = performance.now();
      if (this._pendingFactoryUpdatesCount > 0) {
        yield this.updateMutex.waitForClearAcquireQueue();
      }
      while (this._performUpdateType !== 6) {
        if (performance.now() - start > timeoutMs) {
          throw new Error("waitForUpdate() timeout reached.");
        }
        yield sleep(5);
      }
      yield this.updateMutex.waitForClearAcquireQueue();
    });
  }
  handleOverlays() {
    const hasNoData = !this.series.some((s) => s.hasData());
    this.toggleOverlay(this.overlays.noData, hasNoData);
    if (!hasNoData) {
      const hasNoVisibleSeries = !this.series.some((series) => series.visible);
      this.toggleOverlay(this.overlays.noVisibleSeries, hasNoVisibleSeries);
    }
  }
  toggleOverlay(overlay, visible) {
    if (visible && this.seriesRect) {
      overlay.show(this.seriesRect);
    } else {
      overlay.hide();
    }
  }
  getMinRect() {
    const minRects = this.series.map((series) => series.getMinRect()).filter((rect) => rect !== void 0);
    if (!minRects.length)
      return void 0;
    return new BBox(
      0,
      0,
      minRects.reduce((max, rect) => Math.max(max, rect.width), 0),
      minRects.reduce((max, rect) => Math.max(max, rect.height), 0)
    );
  }
};
__decorateClass([
  ActionOnSet({
    newValue(value) {
      if (this.destroyed)
        return;
      value.setAttribute("data-ag-charts", "");
      value.appendChild(this.element);
      chartsInstances.set(value, this);
    },
    oldValue(value) {
      value.removeAttribute("data-ag-charts");
      value.removeChild(this.element);
      chartsInstances.delete(value);
    }
  })
], Chart.prototype, "container", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      var _a;
      (_a = this.series) == null ? void 0 : _a.forEach((series) => {
        series.setChartData(value);
      });
    }
  })
], Chart.prototype, "data", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      this.resize(value, void 0, "width option");
    }
  })
], Chart.prototype, "width", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      this.resize(void 0, value, "height option");
    }
  })
], Chart.prototype, "height", 2);
__decorateClass([
  ActionOnSet({
    changeValue(value) {
      this.autoSizeChanged(value);
    }
  }),
  Validate(BOOLEAN)
], Chart.prototype, "autoSize", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      var _a;
      (_a = this.scene.root) == null ? void 0 : _a.appendChild(value.node);
    },
    oldValue(oldValue) {
      var _a;
      (_a = this.scene.root) == null ? void 0 : _a.removeChild(oldValue.node);
    }
  })
], Chart.prototype, "title", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      var _a;
      (_a = this.scene.root) == null ? void 0 : _a.appendChild(value.node);
    },
    oldValue(oldValue) {
      var _a;
      (_a = this.scene.root) == null ? void 0 : _a.removeChild(oldValue.node);
    }
  })
], Chart.prototype, "subtitle", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      var _a;
      (_a = this.scene.root) == null ? void 0 : _a.appendChild(value.node);
    },
    oldValue(oldValue) {
      var _a;
      (_a = this.scene.root) == null ? void 0 : _a.removeChild(oldValue.node);
    }
  })
], Chart.prototype, "footnote", 2);
__decorateClass([
  Validate(UNION(["standalone", "integrated"], "a chart mode"))
], Chart.prototype, "mode", 2);
var DataModelSeries = class extends Series {
  isContinuous() {
    var _a, _b;
    const isContinuousX = ContinuousScale.is((_a = this.axes[
      "x"
      /* X */
    ]) == null ? void 0 : _a.scale);
    const isContinuousY = ContinuousScale.is((_b = this.axes[
      "y"
      /* Y */
    ]) == null ? void 0 : _b.scale);
    return { isContinuousX, isContinuousY };
  }
  getModulePropertyDefinitions() {
    return this.moduleMap.mapValues((mod2) => mod2.getPropertyDefinitions(this.isContinuous())).flat();
  }
  // Request data, but with message dispatching to series-options (modules).
  requestDataModel(dataController, data, opts) {
    return __async(this, null, function* () {
      opts.props.push(...this.getModulePropertyDefinitions());
      const { dataModel, processedData } = yield dataController.request(this.id, data != null ? data : [], opts);
      this.dataModel = dataModel;
      this.processedData = processedData;
      this.dispatch("data-processed", { dataModel, processedData });
      return { dataModel, processedData };
    });
  }
  isProcessedDataAnimatable() {
    var _a, _b;
    const validationResults = (_b = (_a = this.processedData) == null ? void 0 : _a.reduced) == null ? void 0 : _b.animationValidation;
    if (!validationResults) {
      return true;
    }
    const { orderedKeys, uniqueKeys } = validationResults;
    return orderedKeys && uniqueKeys;
  }
  checkProcessedDataAnimatable() {
    if (!this.isProcessedDataAnimatable()) {
      this.ctx.animationManager.skipCurrentBatch();
    }
  }
};
var SeriesItemHighlightStyle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = "rgba(255,255,255, 0.33)";
    this.stroke = `rgba(0, 0, 0, 0.4)`;
    this.strokeWidth = 2;
  }
};
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], SeriesItemHighlightStyle.prototype, "fill", 2);
__decorateClass([
  Validate(RATIO, { optional: true })
], SeriesItemHighlightStyle.prototype, "fillOpacity", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], SeriesItemHighlightStyle.prototype, "stroke", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], SeriesItemHighlightStyle.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO, { optional: true })
], SeriesItemHighlightStyle.prototype, "strokeOpacity", 2);
__decorateClass([
  Validate(LINE_DASH, { optional: true })
], SeriesItemHighlightStyle.prototype, "lineDash", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], SeriesItemHighlightStyle.prototype, "lineDashOffset", 2);
var SeriesHighlightStyle = class extends BaseProperties {
};
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], SeriesHighlightStyle.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO, { optional: true })
], SeriesHighlightStyle.prototype, "dimOpacity", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], SeriesHighlightStyle.prototype, "enabled", 2);
var TextHighlightStyle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.color = "black";
  }
};
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], TextHighlightStyle.prototype, "color", 2);
var HighlightStyle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.item = new SeriesItemHighlightStyle();
    this.series = new SeriesHighlightStyle();
    this.text = new TextHighlightStyle();
  }
};
__decorateClass([
  Validate(OBJECT)
], HighlightStyle.prototype, "item", 2);
__decorateClass([
  Validate(OBJECT)
], HighlightStyle.prototype, "series", 2);
__decorateClass([
  Validate(OBJECT)
], HighlightStyle.prototype, "text", 2);
var SeriesProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.visible = true;
    this.showInLegend = true;
    this.cursor = "default";
    this.nodeClickRange = "exact";
    this.highlightStyle = new HighlightStyle();
  }
};
__decorateClass([
  Validate(STRING, { optional: true })
], SeriesProperties.prototype, "id", 2);
__decorateClass([
  Validate(BOOLEAN)
], SeriesProperties.prototype, "visible", 2);
__decorateClass([
  Validate(BOOLEAN)
], SeriesProperties.prototype, "showInLegend", 2);
__decorateClass([
  Validate(STRING)
], SeriesProperties.prototype, "cursor", 2);
__decorateClass([
  Validate(INTERACTION_RANGE)
], SeriesProperties.prototype, "nodeClickRange", 2);
__decorateClass([
  Validate(OBJECT)
], SeriesProperties.prototype, "highlightStyle", 2);
var DEFAULT_DIRECTION_KEYS = {
  [
    "x"
    /* X */
  ]: ["xKey"],
  [
    "y"
    /* Y */
  ]: ["yKey"]
};
var DEFAULT_DIRECTION_NAMES = {
  [
    "x"
    /* X */
  ]: ["xName"],
  [
    "y"
    /* Y */
  ]: ["yName"]
};
var CartesianSeriesNodeClickEvent = class extends SeriesNodeClickEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.xKey = series.properties.xKey;
    this.yKey = series.properties.yKey;
  }
};
var CartesianSeriesProperties = class extends SeriesProperties {
};
__decorateClass([
  Validate(STRING, { optional: true })
], CartesianSeriesProperties.prototype, "legendItemName", 2);
var CartesianSeries = class extends DataModelSeries {
  constructor(_a) {
    var _b = _a, {
      pathsPerSeries = 1,
      hasMarkers = false,
      hasHighlightedLabels = false,
      pathsZIndexSubOrderOffset = [],
      directionKeys = DEFAULT_DIRECTION_KEYS,
      directionNames = DEFAULT_DIRECTION_NAMES,
      datumSelectionGarbageCollection = true,
      markerSelectionGarbageCollection = true,
      animationResetFns
    } = _b, otherOpts = __objRest(_b, [
      "pathsPerSeries",
      "hasMarkers",
      "hasHighlightedLabels",
      "pathsZIndexSubOrderOffset",
      "directionKeys",
      "directionNames",
      "datumSelectionGarbageCollection",
      "markerSelectionGarbageCollection",
      "animationResetFns"
    ]);
    super(__spreadValues({
      directionKeys,
      directionNames,
      useSeriesGroupLayer: true,
      canHaveAxes: true
    }, otherOpts));
    this._contextNodeData = [];
    this.NodeClickEvent = CartesianSeriesNodeClickEvent;
    this.highlightSelection = Selection.select(
      this.highlightNode,
      () => this.opts.hasMarkers ? this.markerFactory() : this.nodeFactory()
    );
    this.highlightLabelSelection = Selection.select(this.highlightLabel, Text);
    this.annotationSelections = /* @__PURE__ */ new Set();
    this.subGroups = [];
    this.subGroupId = 0;
    this.debug = Debug.create();
    this.opts = {
      pathsPerSeries,
      hasMarkers,
      hasHighlightedLabels,
      pathsZIndexSubOrderOffset,
      directionKeys,
      directionNames,
      animationResetFns,
      datumSelectionGarbageCollection,
      markerSelectionGarbageCollection
    };
    this.animationState = new StateMachine(
      "empty",
      {
        empty: {
          update: {
            target: "ready",
            action: (data) => this.animateEmptyUpdateReady(data)
          }
        },
        ready: {
          updateData: "waiting",
          clear: "clearing",
          highlight: (data) => this.animateReadyHighlight(data),
          highlightMarkers: (data) => this.animateReadyHighlightMarkers(data),
          resize: (data) => this.animateReadyResize(data)
        },
        waiting: {
          update: {
            target: "ready",
            action: (data) => this.animateWaitingUpdateReady(data)
          }
        },
        clearing: {
          update: {
            target: "empty",
            action: (data) => this.animateClearingUpdateEmpty(data)
          }
        }
      },
      () => this.checkProcessedDataAnimatable()
    );
  }
  get contextNodeData() {
    return this._contextNodeData.slice();
  }
  addChartEventListeners() {
    this.destroyFns.push(
      this.ctx.chartEventManager.addListener("legend-item-click", (event) => this.onLegendItemClick(event)),
      this.ctx.chartEventManager.addListener(
        "legend-item-double-click",
        (event) => this.onLegendItemDoubleClick(event)
      )
    );
  }
  destroy() {
    super.destroy();
    this._contextNodeData.splice(0, this._contextNodeData.length);
    this.subGroups.splice(0, this.subGroups.length);
  }
  update(_0) {
    return __async(this, arguments, function* ({ seriesRect }) {
      var _a, _b;
      const { visible, _contextNodeData: previousContextData } = this;
      const { series } = (_b = (_a = this.ctx.highlightManager) == null ? void 0 : _a.getActiveHighlight()) != null ? _b : {};
      const seriesHighlighted = series ? series === this : void 0;
      const resize = this.checkResize(seriesRect);
      const highlightItems = yield this.updateHighlightSelection(seriesHighlighted);
      yield this.updateSelections(visible);
      yield this.updateNodes(highlightItems, seriesHighlighted, visible);
      const animationData = this.getAnimationData(seriesRect, previousContextData);
      if (resize) {
        this.animationState.transition("resize", animationData);
      }
      this.animationState.transition("update", animationData);
    });
  }
  updateSelections(anySeriesItemEnabled) {
    return __async(this, null, function* () {
      if (!anySeriesItemEnabled && this.ctx.animationManager.isSkipped()) {
        return;
      }
      if (!this.nodeDataRefresh && !this.isPathOrSelectionDirty()) {
        return;
      }
      if (this.nodeDataRefresh) {
        this.nodeDataRefresh = false;
        this.debug(`CartesianSeries.updateSelections() - calling createNodeData() for`, this.id);
        this._contextNodeData = yield this.createNodeData();
        const animationValid = this.isProcessedDataAnimatable();
        this._contextNodeData.forEach((nodeData) => {
          var _a;
          (_a = nodeData.animationValid) != null ? _a : nodeData.animationValid = animationValid;
        });
        yield this.updateSeriesGroups();
        const { dataModel, processedData } = this;
        if (dataModel !== void 0 && processedData !== void 0) {
          this.dispatch("data-update", { dataModel, processedData });
        }
      }
      yield Promise.all(this.subGroups.map((g, i) => this.updateSeriesGroupSelections(g, i)));
    });
  }
  updateSeriesGroupSelections(subGroup, seriesIdx, seriesHighlighted) {
    return __async(this, null, function* () {
      const { datumSelection, labelSelection, markerSelection, paths } = subGroup;
      const contextData = this._contextNodeData[seriesIdx];
      const { nodeData, labelData, itemId } = contextData;
      yield this.updatePaths({ seriesHighlighted, itemId, contextData, paths, seriesIdx });
      subGroup.datumSelection = yield this.updateDatumSelection({ nodeData, datumSelection, seriesIdx });
      subGroup.labelSelection = yield this.updateLabelSelection({ labelData, labelSelection, seriesIdx });
      if (markerSelection) {
        subGroup.markerSelection = yield this.updateMarkerSelection({ nodeData, markerSelection, seriesIdx });
      }
    });
  }
  markerFactory() {
    const MarkerShape = getMarker();
    return new MarkerShape();
  }
  updateSeriesGroups() {
    return __async(this, null, function* () {
      const {
        _contextNodeData: contextNodeData,
        contentGroup,
        subGroups,
        opts: { pathsPerSeries, hasMarkers, datumSelectionGarbageCollection, markerSelectionGarbageCollection }
      } = this;
      if (contextNodeData.length === subGroups.length) {
        return;
      }
      if (contextNodeData.length < subGroups.length) {
        subGroups.splice(contextNodeData.length).forEach(({ dataNodeGroup, markerGroup, labelGroup, paths }) => {
          contentGroup.removeChild(dataNodeGroup);
          if (markerGroup) {
            contentGroup.removeChild(markerGroup);
          }
          if (labelGroup) {
            contentGroup.removeChild(labelGroup);
          }
          for (const path of paths) {
            contentGroup.removeChild(path);
          }
        });
      }
      const totalGroups = contextNodeData.length;
      while (totalGroups > subGroups.length) {
        const layer = false;
        const subGroupId = this.subGroupId++;
        const dataNodeGroup = new Group({
          name: `${this.id}-series-sub${subGroupId}-dataNodes`,
          layer,
          zIndex: 4,
          zIndexSubOrder: this.getGroupZIndexSubOrder("data", subGroupId)
        });
        const markerGroup = hasMarkers ? new Group({
          name: `${this.id}-series-sub${this.subGroupId++}-markers`,
          layer,
          zIndex: 4,
          zIndexSubOrder: this.getGroupZIndexSubOrder("marker", subGroupId)
        }) : void 0;
        const labelGroup = new Group({
          name: `${this.id}-series-sub${this.subGroupId++}-labels`,
          layer,
          zIndex: 7,
          zIndexSubOrder: this.getGroupZIndexSubOrder("labels", subGroupId)
        });
        contentGroup.appendChild(dataNodeGroup);
        contentGroup.appendChild(labelGroup);
        if (markerGroup) {
          contentGroup.appendChild(markerGroup);
        }
        const paths = [];
        for (let index = 0; index < pathsPerSeries; index++) {
          paths[index] = new Path();
          paths[index].zIndex = 4;
          paths[index].zIndexSubOrder = this.getGroupZIndexSubOrder("paths", index);
          contentGroup.appendChild(paths[index]);
        }
        subGroups.push({
          paths,
          dataNodeGroup,
          markerGroup,
          labelGroup,
          labelSelection: Selection.select(labelGroup, Text),
          datumSelection: Selection.select(
            dataNodeGroup,
            () => this.nodeFactory(),
            datumSelectionGarbageCollection
          ),
          markerSelection: markerGroup ? Selection.select(markerGroup, () => this.markerFactory(), markerSelectionGarbageCollection) : void 0
        });
      }
    });
  }
  getGroupZIndexSubOrder(type, subIndex = 0) {
    var _a;
    const result = super.getGroupZIndexSubOrder(type, subIndex);
    if (type === "paths") {
      const pathOffset = (_a = this.opts.pathsZIndexSubOrderOffset[subIndex]) != null ? _a : 0;
      const superFn = result[0];
      if (typeof superFn === "function") {
        result[0] = () => +superFn() + pathOffset;
      } else {
        result[0] = +superFn + pathOffset;
      }
    }
    return result;
  }
  updateNodes(highlightedItems, seriesHighlighted, anySeriesItemEnabled) {
    return __async(this, null, function* () {
      var _a;
      const {
        highlightSelection,
        highlightLabelSelection,
        opts: { hasMarkers, hasHighlightedLabels }
      } = this;
      const animationEnabled = !this.ctx.animationManager.isSkipped();
      const visible = this.visible && ((_a = this._contextNodeData) == null ? void 0 : _a.length) > 0 && anySeriesItemEnabled;
      this.rootGroup.visible = animationEnabled || visible;
      this.contentGroup.visible = animationEnabled || visible;
      this.highlightGroup.visible = (animationEnabled || visible) && !!seriesHighlighted;
      const subGroupOpacity = this.getOpacity();
      if (hasMarkers) {
        yield this.updateMarkerNodes({
          markerSelection: highlightSelection,
          isHighlight: true,
          seriesIdx: -1
        });
        this.animationState.transition("highlightMarkers", highlightSelection);
      } else {
        yield this.updateDatumNodes({
          datumSelection: highlightSelection,
          isHighlight: true,
          seriesIdx: -1
        });
        this.animationState.transition("highlight", highlightSelection);
      }
      if (hasHighlightedLabels) {
        yield this.updateLabelNodes({ labelSelection: highlightLabelSelection, seriesIdx: -1 });
      }
      yield Promise.all(
        this.subGroups.map((subGroup, seriesIdx) => __async(this, null, function* () {
          const {
            dataNodeGroup,
            markerGroup,
            datumSelection,
            labelSelection,
            markerSelection,
            paths,
            labelGroup
          } = subGroup;
          const { itemId } = this.contextNodeData[seriesIdx];
          const subGroupVisible = visible;
          dataNodeGroup.opacity = subGroupOpacity;
          dataNodeGroup.visible = animationEnabled || subGroupVisible;
          labelGroup.visible = subGroupVisible;
          if (markerGroup) {
            markerGroup.opacity = subGroupOpacity;
            markerGroup.zIndex = dataNodeGroup.zIndex >= 4 ? dataNodeGroup.zIndex : dataNodeGroup.zIndex + 1;
            markerGroup.visible = subGroupVisible;
          }
          if (labelGroup) {
            labelGroup.opacity = subGroupOpacity;
          }
          yield this.updatePathNodes({
            seriesHighlighted,
            itemId,
            paths,
            seriesIdx,
            opacity: subGroupOpacity,
            visible: subGroupVisible,
            animationEnabled
          });
          if (!dataNodeGroup.visible) {
            return;
          }
          yield this.updateDatumNodes({ datumSelection, highlightedItems, isHighlight: false, seriesIdx });
          yield this.updateLabelNodes({ labelSelection, seriesIdx });
          if (hasMarkers && markerSelection) {
            yield this.updateMarkerNodes({ markerSelection, isHighlight: false, seriesIdx });
          }
        }))
      );
    });
  }
  getHighlightLabelData(labelData, highlightedItem) {
    const labelItems = labelData.filter(
      (ld) => ld.datum === highlightedItem.datum && ld.itemId === highlightedItem.itemId
    );
    return labelItems.length !== 0 ? labelItems : void 0;
  }
  getHighlightData(_nodeData, highlightedItem) {
    return highlightedItem ? [highlightedItem] : void 0;
  }
  updateHighlightSelection(seriesHighlighted) {
    return __async(this, null, function* () {
      var _a;
      const { highlightSelection, highlightLabelSelection, _contextNodeData: contextNodeData } = this;
      const highlightedDatum = (_a = this.ctx.highlightManager) == null ? void 0 : _a.getActiveHighlight();
      const item = seriesHighlighted && (highlightedDatum == null ? void 0 : highlightedDatum.datum) ? highlightedDatum : void 0;
      let labelItems;
      let highlightItems;
      if (item != null) {
        const labelsEnabled = this.isLabelEnabled();
        for (const { labelData, nodeData } of contextNodeData) {
          highlightItems = this.getHighlightData(nodeData, item);
          labelItems = labelsEnabled ? this.getHighlightLabelData(labelData, item) : void 0;
          if ((!labelsEnabled || labelItems != null) && highlightItems != null) {
            break;
          }
        }
      }
      this.highlightSelection = yield this.updateHighlightSelectionItem({
        items: highlightItems,
        highlightSelection
      });
      this.highlightLabelSelection = yield this.updateHighlightSelectionLabel({
        items: labelItems,
        highlightLabelSelection
      });
      return highlightItems;
    });
  }
  pickNodeExactShape(point) {
    var _a;
    const result = super.pickNodeExactShape(point);
    if (result) {
      return result;
    }
    const { x, y } = point;
    const {
      opts: { hasMarkers }
    } = this;
    let match;
    for (const { dataNodeGroup, markerGroup } of this.subGroups) {
      let match2 = dataNodeGroup.pickNode(x, y);
      if (!match2 && hasMarkers) {
        match2 = markerGroup == null ? void 0 : markerGroup.pickNode(x, y);
      }
      if (match2) {
        break;
      }
    }
    if (match) {
      return { datum: match.datum, distance: 0 };
    } else {
      for (const mod2 of this.moduleMap.modules) {
        const { datum } = (_a = mod2.pickNodeExact(point)) != null ? _a : {};
        if (datum !== void 0) {
          return { datum, distance: 0 };
        }
      }
    }
  }
  pickNodeClosestDatum(point) {
    var _a, _b;
    const { x, y } = point;
    const { axes, rootGroup, _contextNodeData: contextNodeData } = this;
    const xAxis = axes[
      "x"
      /* X */
    ];
    const yAxis = axes[
      "y"
      /* Y */
    ];
    const hitPoint = rootGroup.transformPoint(x, y);
    let minDistance = Infinity;
    let closestDatum;
    for (const context of contextNodeData) {
      for (const datum of context.nodeData) {
        const { point: { x: datumX = NaN, y: datumY = NaN } = {} } = datum;
        if (isNaN(datumX) || isNaN(datumY)) {
          continue;
        }
        const isInRange = (xAxis == null ? void 0 : xAxis.inRange(datumX)) && (yAxis == null ? void 0 : yAxis.inRange(datumY));
        if (!isInRange) {
          continue;
        }
        const distance = Math.max(__pow(hitPoint.x - datumX, 2) + __pow(hitPoint.y - datumY, 2), 0);
        if (distance < minDistance) {
          minDistance = distance;
          closestDatum = datum;
        }
      }
    }
    for (const mod2 of this.moduleMap.modules) {
      const modPick = mod2.pickNodeNearest(point);
      if (modPick !== void 0 && modPick.distanceSquared < minDistance) {
        minDistance = modPick.distanceSquared;
        closestDatum = modPick.datum;
        break;
      }
    }
    if (closestDatum) {
      const distance = Math.max(Math.sqrt(minDistance) - ((_b = (_a = closestDatum.point) == null ? void 0 : _a.size) != null ? _b : 0), 0);
      return { datum: closestDatum, distance };
    }
  }
  pickNodeMainAxisFirst(point, requireCategoryAxis) {
    var _a, _b;
    const { x, y } = point;
    const { axes, rootGroup, _contextNodeData: contextNodeData } = this;
    const xAxis = axes[
      "x"
      /* X */
    ];
    const yAxis = axes[
      "y"
      /* Y */
    ];
    const directions2 = [xAxis, yAxis].filter((a) => a instanceof CategoryAxis).map((a) => a.direction);
    if (requireCategoryAxis && directions2.length === 0) {
      return;
    }
    const [
      primaryDirection = "x"
      /* X */
    ] = directions2;
    const hitPoint = rootGroup.transformPoint(x, y);
    const hitPointCoords = primaryDirection === "x" ? [hitPoint.x, hitPoint.y] : [hitPoint.y, hitPoint.x];
    const minDistance = [Infinity, Infinity];
    let closestDatum;
    for (const context of contextNodeData) {
      for (const datum of context.nodeData) {
        const { point: { x: datumX = NaN, y: datumY = NaN } = {} } = datum;
        if (isNaN(datumX) || isNaN(datumY)) {
          continue;
        }
        const isInRange = (xAxis == null ? void 0 : xAxis.inRange(datumX)) && (yAxis == null ? void 0 : yAxis.inRange(datumY));
        if (!isInRange) {
          continue;
        }
        const point2 = primaryDirection === "x" ? [datumX, datumY] : [datumY, datumX];
        let newMinDistance = true;
        for (let i = 0; i < point2.length; i++) {
          const dist = Math.abs(point2[i] - hitPointCoords[i]);
          if (dist > minDistance[i]) {
            newMinDistance = false;
            break;
          }
          if (dist < minDistance[i]) {
            minDistance[i] = dist;
            minDistance.fill(Infinity, i + 1, minDistance.length);
          }
        }
        if (newMinDistance) {
          closestDatum = datum;
        }
      }
    }
    if (closestDatum) {
      let closestDistanceSquared = Math.max(
        __pow(minDistance[0], 2) + __pow(minDistance[1], 2) - ((_b = (_a = closestDatum.point) == null ? void 0 : _a.size) != null ? _b : 0),
        0
      );
      for (const mod2 of this.moduleMap.modules) {
        const modPick = mod2.pickNodeMainAxisFirst(point);
        if (modPick !== void 0 && modPick.distanceSquared < closestDistanceSquared) {
          closestDatum = modPick.datum;
          closestDistanceSquared = modPick.distanceSquared;
          break;
        }
      }
      return { datum: closestDatum, distance: Math.sqrt(closestDistanceSquared) };
    }
  }
  onLegendItemClick(event) {
    const { legendItemName } = this.properties;
    const { enabled, itemId, series } = event;
    const matchedLegendItemName = legendItemName != null && legendItemName === event.legendItemName;
    if (series.id === this.id || matchedLegendItemName) {
      this.toggleSeriesItem(itemId, enabled);
    }
  }
  onLegendItemDoubleClick(event) {
    const { enabled, itemId, series, numVisibleItems } = event;
    const { legendItemName } = this.properties;
    const matchedLegendItemName = legendItemName != null && legendItemName === event.legendItemName;
    if (series.id === this.id || matchedLegendItemName) {
      this.toggleSeriesItem(itemId, true);
    } else if (enabled && numVisibleItems === 1) {
      this.toggleSeriesItem(itemId, true);
    } else {
      this.toggleSeriesItem(itemId, false);
    }
  }
  isPathOrSelectionDirty() {
    return false;
  }
  getLabelData() {
    return [];
  }
  shouldFlipXY() {
    return false;
  }
  /**
   * Get the minimum bounding box that contains any adjacent two nodes. The axes are treated independently, so this
   * may not represent the same two points for both directions. The dimensions represent the greatest distance
   * between any two adjacent nodes.
   */
  getMinRect() {
    const [context] = this._contextNodeData;
    if (!(context == null ? void 0 : context.nodeData.length)) {
      return;
    }
    const width = context.nodeData.map(({ midPoint }) => {
      var _a;
      return (_a = midPoint == null ? void 0 : midPoint.x) != null ? _a : 0;
    }).sort((a, b) => a - b).reduce((max, x, i, array) => i > 0 ? Math.max(max, x - array[i - 1]) : max, 0);
    const height = context.nodeData.map(({ midPoint }) => {
      var _a;
      return (_a = midPoint == null ? void 0 : midPoint.y) != null ? _a : 0;
    }).sort((a, b) => a - b).reduce((max, y, i, array) => i > 0 ? Math.max(max, y - array[i - 1]) : max, 0);
    return new BBox(0, 0, width, height);
  }
  updateHighlightSelectionItem(opts) {
    return __async(this, null, function* () {
      const {
        opts: { hasMarkers }
      } = this;
      const { items, highlightSelection } = opts;
      const nodeData = items != null ? items : [];
      if (hasMarkers) {
        const markerSelection = highlightSelection;
        return this.updateMarkerSelection({ nodeData, markerSelection, seriesIdx: -1 });
      } else {
        return this.updateDatumSelection({
          nodeData,
          datumSelection: highlightSelection,
          seriesIdx: -1
        });
      }
    });
  }
  updateHighlightSelectionLabel(opts) {
    return __async(this, null, function* () {
      var _a;
      return this.updateLabelSelection({
        labelData: (_a = opts.items) != null ? _a : [],
        labelSelection: opts.highlightLabelSelection,
        seriesIdx: -1
      });
    });
  }
  updateDatumSelection(opts) {
    return __async(this, null, function* () {
      return opts.datumSelection;
    });
  }
  updateDatumNodes(_opts) {
    return __async(this, null, function* () {
    });
  }
  updateMarkerSelection(opts) {
    return __async(this, null, function* () {
      return opts.markerSelection;
    });
  }
  updateMarkerNodes(_opts) {
    return __async(this, null, function* () {
    });
  }
  updatePaths(opts) {
    return __async(this, null, function* () {
      opts.paths.forEach((p) => p.visible = false);
    });
  }
  updatePathNodes(opts) {
    return __async(this, null, function* () {
      const { paths, opacity, visible } = opts;
      for (const path of paths) {
        path.opacity = opacity;
        path.visible = visible;
      }
    });
  }
  resetAllAnimation(data) {
    var _a, _b;
    const { path, datum, label, marker } = (_b = (_a = this.opts) == null ? void 0 : _a.animationResetFns) != null ? _b : {};
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    if (path) {
      data.paths.forEach((paths) => {
        resetMotion(paths, path);
      });
    }
    if (datum) {
      resetMotion(data.datumSelections, datum);
    }
    if (label) {
      resetMotion(data.labelSelections, label);
    }
    if (marker) {
      resetMotion(data.markerSelections, marker);
    }
    if (data.contextData.some((d) => d.animationValid === false)) {
      this.ctx.animationManager.skipCurrentBatch();
    }
  }
  animateEmptyUpdateReady(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animateWaitingUpdateReady(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animateReadyHighlight(data) {
    var _a, _b;
    const { datum } = (_b = (_a = this.opts) == null ? void 0 : _a.animationResetFns) != null ? _b : {};
    if (datum) {
      resetMotion([data], datum);
    }
  }
  animateReadyHighlightMarkers(data) {
    var _a, _b;
    const { marker } = (_b = (_a = this.opts) == null ? void 0 : _a.animationResetFns) != null ? _b : {};
    if (marker) {
      resetMotion([data], marker);
    }
  }
  animateReadyResize(data) {
    this.resetAllAnimation(data);
  }
  animateClearingUpdateEmpty(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animationTransitionClear() {
    this.animationState.transition("clear", this.getAnimationData());
  }
  getAnimationData(seriesRect, previousContextData) {
    const animationData = {
      datumSelections: this.subGroups.map(({ datumSelection }) => datumSelection),
      markerSelections: this.subGroups.filter(({ markerSelection }) => markerSelection !== void 0).map(({ markerSelection }) => markerSelection),
      labelSelections: this.subGroups.map(({ labelSelection }) => labelSelection),
      annotationSelections: [...this.annotationSelections],
      contextData: this._contextNodeData,
      previousContextData,
      paths: this.subGroups.map(({ paths }) => paths),
      seriesRect
    };
    return animationData;
  }
  calculateScaling() {
    const result = {};
    const addScale = (direction) => {
      const axis = this.axes[direction];
      if (!axis)
        return;
      if (axis.scale instanceof LogScale) {
        const { range: range3, domain } = axis.scale;
        result[direction] = {
          type: "log",
          convert: (domain2) => axis.scale.convert(domain2),
          domain: [domain[0], domain[1]],
          range: [range3[0], range3[1]]
        };
      } else if (axis.scale instanceof ContinuousScale) {
        const { range: range3 } = axis.scale;
        const domain = axis.scale.getDomain();
        result[direction] = {
          type: "continuous",
          domain: [domain[0], domain[1]],
          range: [range3[0], range3[1]]
        };
      } else if (axis.scale) {
        const { domain } = axis.scale;
        result[direction] = {
          type: "category",
          domain,
          range: domain.map((d) => axis.scale.convert(d))
        };
      }
    };
    addScale(
      "x"
      /* X */
    );
    addScale(
      "y"
      /* Y */
    );
    return result;
  }
};
var directions = ["top", "right", "bottom", "left"];
var _CartesianChart = class _CartesianChart2 extends Chart {
  constructor(specialOverrides, resources) {
    super(specialOverrides, resources);
    this.paired = true;
    this._lastCrossLineIds = void 0;
    this._lastAxisWidths = {
      top: 0,
      bottom: 0,
      left: 0,
      right: 0
    };
    this._lastVisibility = {
      crossLines: true,
      series: true
    };
  }
  performLayout() {
    return __async(this, null, function* () {
      const shrinkRect = yield __superGet(_CartesianChart2.prototype, this, "performLayout").call(this);
      const { animationRect, seriesRect, visibility, clipSeries } = this.updateAxes(shrinkRect);
      this.seriesRoot.visible = visibility.series;
      this.seriesRect = seriesRect;
      this.animationRect = animationRect;
      this.seriesRoot.translationX = Math.floor(seriesRect.x);
      this.seriesRoot.translationY = Math.floor(seriesRect.y);
      const {
        seriesArea: { padding }
      } = this;
      const seriesPaddedRect = seriesRect.clone().grow({
        top: padding.top,
        right: padding.right,
        bottom: padding.bottom,
        left: padding.left
      });
      this.hoverRect = seriesPaddedRect;
      this.layoutService.dispatchLayoutComplete({
        type: "layout-complete",
        chart: { width: this.scene.width, height: this.scene.height },
        clipSeries,
        series: {
          rect: seriesRect,
          paddedRect: seriesPaddedRect,
          visible: visibility.series,
          shouldFlipXY: this.shouldFlipXY()
        },
        axes: this.axes.map((axis) => __spreadValues({ id: axis.id }, axis.getLayoutState()))
      });
      return shrinkRect;
    });
  }
  updateAxes(inputShrinkRect) {
    var _a;
    const crossLineIds = this.axes.flatMap((axis) => {
      var _a2;
      return (_a2 = axis.crossLines) != null ? _a2 : [];
    }).map((crossLine) => crossLine.id);
    const axesValid = this._lastCrossLineIds != null && this._lastCrossLineIds.length === crossLineIds.length && this._lastCrossLineIds.every((id, index) => crossLineIds[index] === id);
    let axisWidths;
    let visibility;
    if (axesValid) {
      axisWidths = __spreadValues({}, this._lastAxisWidths);
      visibility = __spreadValues({}, this._lastVisibility);
    } else {
      axisWidths = { top: 0, bottom: 0, left: 0, right: 0 };
      visibility = { crossLines: true, series: true };
      this._lastCrossLineIds = crossLineIds;
    }
    const liveAxisWidths = new Set(this._axes.map((a) => a.position));
    for (const position of Object.keys(axisWidths)) {
      if (!liveAxisWidths.has(position)) {
        delete axisWidths[position];
      }
    }
    const stableOutputs = (otherAxisWidths, otherVisibility) => {
      if (Object.keys(otherAxisWidths).some((k) => axisWidths[k] == null)) {
        return false;
      }
      return visibility.crossLines === otherVisibility.crossLines && visibility.series === otherVisibility.series && // Check for existing axis positions and equality.
      Object.entries(axisWidths).every(([p, w]) => {
        const otherW = otherAxisWidths[p];
        if (w != null || otherW != null) {
          return w === otherW;
        }
        return true;
      });
    };
    const ceilValues = (records) => {
      return Object.entries(records).reduce((out, [key, value]) => {
        if (value && Math.abs(value) === Infinity) {
          value = 0;
        }
        out[key] = value != null ? Math.ceil(value) : value;
        return out;
      }, {});
    };
    let lastPassAxisWidths = {};
    let lastPassVisibility = {};
    let clipSeries = false;
    let seriesRect = (_a = this.seriesRect) == null ? void 0 : _a.clone();
    let count2 = 0;
    let primaryTickCounts = {};
    do {
      Object.assign(axisWidths, lastPassAxisWidths);
      Object.assign(visibility, lastPassVisibility);
      const result = this.updateAxesPass(axisWidths, inputShrinkRect.clone(), seriesRect);
      lastPassAxisWidths = ceilValues(result.axisWidths);
      lastPassVisibility = result.visibility;
      clipSeries = result.clipSeries;
      seriesRect = result.seriesRect;
      primaryTickCounts = result.primaryTickCounts;
      if (count2++ > 10) {
        Logger.warn("unable to find stable axis layout.");
        break;
      }
    } while (!stableOutputs(lastPassAxisWidths, lastPassVisibility));
    this.axes.forEach((axis) => {
      const { direction } = axis;
      const primaryTickCount = primaryTickCounts[direction];
      axis.update(primaryTickCount);
    });
    const clipRectPadding = 5;
    this.axes.forEach((axis) => {
      axis.setCrossLinesVisible(visibility.crossLines);
      if (!seriesRect) {
        return;
      }
      axis.clipGrid(
        seriesRect.x,
        seriesRect.y,
        seriesRect.width + clipRectPadding,
        seriesRect.height + clipRectPadding
      );
      switch (axis.position) {
        case "left":
        case "right":
          axis.clipTickLines(
            inputShrinkRect.x,
            seriesRect.y,
            inputShrinkRect.width + clipRectPadding,
            seriesRect.height + clipRectPadding
          );
          break;
        case "top":
        case "bottom":
          axis.clipTickLines(
            seriesRect.x,
            inputShrinkRect.y,
            seriesRect.width + clipRectPadding,
            inputShrinkRect.height + clipRectPadding
          );
          break;
      }
    });
    this._lastAxisWidths = axisWidths;
    this._lastVisibility = visibility;
    return { seriesRect, animationRect: inputShrinkRect, visibility, clipSeries };
  }
  updateAxesPass(axisWidths, bounds, lastPassSeriesRect) {
    const { axes } = this;
    const visited = {};
    const newAxisWidths = {};
    const visibility = {
      series: true,
      crossLines: true
    };
    let clipSeries = false;
    const primaryTickCounts = {};
    const paddedBounds = this.applySeriesPadding(bounds);
    const crossLinePadding = lastPassSeriesRect ? this.buildCrossLinePadding(axisWidths) : {};
    const axisBound = this.buildAxisBound(paddedBounds, axisWidths, crossLinePadding, visibility);
    const seriesRect = this.buildSeriesRect(axisBound, axisWidths);
    axes.forEach((axis) => {
      var _a, _b;
      const { position = "left" } = axis;
      const {
        clipSeries: newClipSeries,
        axisThickness,
        axisOffset
      } = this.calculateAxisDimensions({
        axis,
        seriesRect,
        paddedBounds,
        axisWidths,
        newAxisWidths,
        primaryTickCounts,
        clipSeries,
        addInterAxisPadding: ((_a = visited[position]) != null ? _a : 0) > 0
      });
      visited[position] = ((_b = visited[position]) != null ? _b : 0) + 1;
      clipSeries = clipSeries || newClipSeries;
      this.positionAxis({
        axis,
        axisBound,
        axisOffset,
        axisThickness,
        axisWidths,
        primaryTickCounts,
        seriesRect
      });
    });
    return { clipSeries, seriesRect, axisWidths: newAxisWidths, visibility, primaryTickCounts };
  }
  buildCrossLinePadding(axisWidths) {
    var _a;
    const crossLinePadding = {};
    this.axes.forEach((axis) => {
      if (axis.crossLines) {
        axis.crossLines.forEach((crossLine) => {
          crossLine.calculatePadding(crossLinePadding);
        });
      }
    });
    for (const [side, padding = 0] of Object.entries(crossLinePadding)) {
      crossLinePadding[side] = Math.max(padding - ((_a = axisWidths[side]) != null ? _a : 0), 0);
    }
    return crossLinePadding;
  }
  applySeriesPadding(bounds) {
    const paddedRect = bounds.clone();
    const reversedAxes = this.axes.slice().reverse();
    directions.forEach((dir) => {
      const padding = this.seriesArea.padding[dir];
      const axis = reversedAxes.find((axis2) => axis2.position === dir);
      if (axis) {
        axis.seriesAreaPadding = padding;
      } else {
        paddedRect.shrink(padding, dir);
      }
    });
    return paddedRect;
  }
  buildAxisBound(bounds, axisWidths, crossLinePadding, visibility) {
    var _a, _b, _c, _d;
    const result = bounds.clone();
    const { top = 0, right = 0, bottom = 0, left = 0 } = crossLinePadding;
    const horizontalPadding = left + right;
    const verticalPadding = top + bottom;
    const totalWidth = ((_a = axisWidths.left) != null ? _a : 0) + ((_b = axisWidths.right) != null ? _b : 0) + horizontalPadding;
    const totalHeight = ((_c = axisWidths.top) != null ? _c : 0) + ((_d = axisWidths.bottom) != null ? _d : 0) + verticalPadding;
    if (result.width <= totalWidth || result.height <= totalHeight) {
      visibility.crossLines = false;
      visibility.series = false;
      return result;
    }
    result.x += left;
    result.y += top;
    result.width -= horizontalPadding;
    result.height -= verticalPadding;
    return result;
  }
  buildSeriesRect(axisBound, axisWidths) {
    const result = axisBound.clone();
    const { top, bottom, left, right } = axisWidths;
    result.x += left != null ? left : 0;
    result.y += top != null ? top : 0;
    result.width -= (left != null ? left : 0) + (right != null ? right : 0);
    result.height -= (top != null ? top : 0) + (bottom != null ? bottom : 0);
    result.width = Math.max(0, result.width);
    result.height = Math.max(0, result.height);
    return result;
  }
  clampToOutsideSeriesRect(seriesRect, value, dimension, direction) {
    const { x, y, width, height } = seriesRect;
    const clampBounds = [x, y, x + width, y + height];
    const fn = direction === 1 ? Math.min : Math.max;
    const compareTo = clampBounds[(dimension === "x" ? 0 : 1) + (direction === 1 ? 0 : 2)];
    return fn(value, compareTo);
  }
  calculateAxisDimensions(opts) {
    var _a, _b, _c, _d, _e;
    const { axis, seriesRect, paddedBounds, axisWidths, newAxisWidths, primaryTickCounts, addInterAxisPadding } = opts;
    let { clipSeries } = opts;
    const { position = "left", direction } = axis;
    const axisLeftRightRange = (axis2) => {
      if (axis2 instanceof CategoryAxis || axis2 instanceof GroupedCategoryAxis) {
        return [0, seriesRect.height];
      }
      return [seriesRect.height, 0];
    };
    const axisOffset = (_a = newAxisWidths[position]) != null ? _a : 0;
    switch (position) {
      case "top":
      case "bottom":
        axis.range = [0, seriesRect.width];
        axis.gridLength = seriesRect.height;
        break;
      case "right":
      case "left":
        axis.range = axisLeftRightRange(axis);
        axis.gridLength = seriesRect.width;
        break;
    }
    const zoom = this.zoomManager.getAxisZoom(axis.id);
    const { min = 0, max = 1 } = zoom != null ? zoom : {};
    axis.visibleRange = [min, max];
    const rangeClipped = axis.dataDomain.clipped || axis.visibleRange[0] > 0 || axis.visibleRange[1] < 1;
    clipSeries || (clipSeries = rangeClipped);
    let primaryTickCount = axis.nice ? primaryTickCounts[direction] : void 0;
    const paddedBoundsCoefficient = 0.3;
    if (axis.thickness != null && axis.thickness > 0) {
      axis.maxThickness = axis.thickness;
    } else if (direction === "y") {
      axis.maxThickness = paddedBounds.width * paddedBoundsCoefficient;
    } else {
      axis.maxThickness = paddedBounds.height * paddedBoundsCoefficient;
    }
    const layout = axis.calculateLayout(primaryTickCount);
    primaryTickCount = layout.primaryTickCount;
    primaryTickCounts[direction] = (_b = primaryTickCounts[direction]) != null ? _b : primaryTickCount;
    let axisThickness = 0;
    if (axis.thickness != null && axis.thickness > 0) {
      axisThickness = axis.thickness;
    } else {
      const { bbox } = layout;
      axisThickness = direction === "x" ? bbox.height : bbox.width;
    }
    const axisPadding = 15;
    if (addInterAxisPadding) {
      axisThickness += axisPadding;
    }
    axisThickness = Math.ceil(axisThickness);
    newAxisWidths[position] = ((_c = newAxisWidths[position]) != null ? _c : 0) + axisThickness;
    axis.gridPadding = ((_d = axisWidths[position]) != null ? _d : 0) - ((_e = newAxisWidths[position]) != null ? _e : 0);
    return { clipSeries, axisThickness, axisOffset, primaryTickCount };
  }
  positionAxis(opts) {
    var _a, _b, _c, _d;
    const { axis, axisBound, axisWidths, seriesRect, axisOffset, axisThickness } = opts;
    const { position } = axis;
    switch (position) {
      case "top":
        axis.translation.x = axisBound.x + ((_a = axisWidths.left) != null ? _a : 0);
        axis.translation.y = this.clampToOutsideSeriesRect(
          seriesRect,
          axisBound.y + 1 + axisOffset + axisThickness,
          "y",
          1
        );
        break;
      case "bottom":
        axis.translation.x = axisBound.x + ((_b = axisWidths.left) != null ? _b : 0);
        axis.translation.y = this.clampToOutsideSeriesRect(
          seriesRect,
          axisBound.y + axisBound.height + 1 - axisThickness - axisOffset,
          "y",
          -1
        );
        break;
      case "left":
        axis.translation.y = axisBound.y + ((_c = axisWidths.top) != null ? _c : 0);
        axis.translation.x = this.clampToOutsideSeriesRect(
          seriesRect,
          axisBound.x + axisOffset + axisThickness,
          "x",
          1
        );
        break;
      case "right":
        axis.translation.y = axisBound.y + ((_d = axisWidths.top) != null ? _d : 0);
        axis.translation.x = this.clampToOutsideSeriesRect(
          seriesRect,
          axisBound.x + axisBound.width - axisThickness - axisOffset,
          "x",
          -1
        );
        break;
    }
    axis.updatePosition({ rotation: toRadians(axis.rotation), sideFlag: axis.label.getSideFlag() });
  }
  shouldFlipXY() {
    return !this.series.some((series) => !(series instanceof CartesianSeries && series.shouldFlipXY()));
  }
};
_CartesianChart.className = "CartesianChart";
_CartesianChart.type = "cartesian";
var CartesianChart = _CartesianChart;
var AgChartInstanceProxy = class _AgChartInstanceProxy {
  constructor(chart) {
    this.chart = chart;
  }
  static isInstance(x) {
    var _a;
    if (x instanceof _AgChartInstanceProxy) {
      return true;
    }
    if (((_a = x.constructor) == null ? void 0 : _a.name) === "AgChartInstanceProxy" && x.chart != null) {
      return true;
    }
    return x.chart != null && this.validateImplementation(x);
  }
  static validateImplementation(x) {
    var _a, _b;
    const chartProps = ["getOptions", "destroy"];
    const signatureProps = Object.keys((_b = (_a = x.constructor) == null ? void 0 : _a.prototype) != null ? _b : {});
    return chartProps.every((prop) => signatureProps.includes(prop));
  }
  getOptions() {
    return this.chart.getOptions();
  }
  destroy() {
    this.chart.destroy();
  }
};
function calculateNiceSecondaryAxis(domain, primaryTickCount, reverse) {
  let start = Math.floor(Math.min(domain[0], domain[1]));
  let stop = Math.max(domain[0], domain[1]);
  start = calculateNiceStart(start, stop, primaryTickCount);
  const step = getTickStep(start, stop, primaryTickCount);
  const segments = primaryTickCount - 1;
  stop = start + segments * step;
  const d = reverse ? [stop, start] : [start, stop];
  const ticks = getTicks(start, step, primaryTickCount);
  return [d, ticks];
}
function calculateNiceStart(a, b, count2) {
  const rawStep = Math.abs(b - a) / (count2 - 1);
  const order = Math.floor(Math.log10(rawStep));
  const magnitude = Math.pow(10, order);
  return Math.floor(a / magnitude) * magnitude;
}
function getTicks(start, step, count2) {
  const stepPower = Math.floor(Math.log10(step));
  const fractionDigits = step > 0 && step < 1 ? Math.abs(stepPower) : 0;
  const f = Math.pow(10, fractionDigits);
  const ticks = createNumericTicks(fractionDigits);
  for (let i = 0; i < count2; i++) {
    const tick = start + step * i;
    ticks[i] = Math.round(tick * f) / f;
  }
  return ticks;
}
function getTickStep(start, stop, count2) {
  const segments = count2 - 1;
  const rawStep = (stop - start) / segments;
  return calculateNextNiceStep(rawStep);
}
function calculateNextNiceStep(rawStep) {
  const order = Math.floor(Math.log10(rawStep));
  const magnitude = Math.pow(10, order);
  const step = rawStep / magnitude * 10;
  if (step > 0 && step <= 1) {
    return magnitude / 10;
  }
  if (step > 1 && step <= 2) {
    return 2 * magnitude / 10;
  }
  if (step > 1 && step <= 5) {
    return 5 * magnitude / 10;
  }
  if (step > 5 && step <= 10) {
    return 10 * magnitude / 10;
  }
  if (step > 10 && step <= 20) {
    return 20 * magnitude / 10;
  }
  if (step > 20 && step <= 40) {
    return 40 * magnitude / 10;
  }
  if (step > 40 && step <= 50) {
    return 50 * magnitude / 10;
  }
  if (step > 50 && step <= 100) {
    return 100 * magnitude / 10;
  }
  return step;
}
var NumberAxisTick = class extends AxisTick {
  constructor() {
    super(...arguments);
    this.maxSpacing = NaN;
  }
};
__decorateClass([
  Validate(OR(AND(NUMBER.restrict({ min: 1 }), GREATER_THAN("minSpacing")), NAN)),
  Default(NaN)
], NumberAxisTick.prototype, "maxSpacing", 2);
var NumberAxis = class extends CartesianAxis {
  constructor(moduleCtx, scale2 = new LinearScale()) {
    super(moduleCtx, scale2);
    this.min = NaN;
    this.max = NaN;
  }
  normaliseDataDomain(d) {
    const { min, max } = this;
    const { extent: extent2, clipped } = normalisedExtentWithMetadata(d, min, max);
    return { domain: extent2, clipped };
  }
  formatDatum(datum) {
    if (typeof datum === "number") {
      return datum.toFixed(2);
    } else {
      Logger.warnOnce(
        "data contains Date objects which are being plotted against a number axis, please only use a number axis for numbers."
      );
      return String(datum);
    }
  }
  createTick() {
    return new NumberAxisTick();
  }
  updateSecondaryAxisTicks(primaryTickCount) {
    if (this.dataDomain == null) {
      throw new Error("AG Charts - dataDomain not calculated, cannot perform tick calculation.");
    }
    if (this.dataDomain.domain.length === 0)
      return [];
    const [d, ticks] = calculateNiceSecondaryAxis(this.dataDomain.domain, primaryTickCount != null ? primaryTickCount : 0, this.reverse);
    this.scale.nice = false;
    this.scale.domain = d;
    this.scale.update();
    return ticks;
  }
};
NumberAxis.className = "NumberAxis";
NumberAxis.type = "number";
__decorateClass([
  Validate(AND(NUMBER_OR_NAN, LESS_THAN("max"))),
  Default(NaN)
], NumberAxis.prototype, "min", 2);
__decorateClass([
  Validate(AND(NUMBER_OR_NAN, GREATER_THAN("min"))),
  Default(NaN)
], NumberAxis.prototype, "max", 2);
var NON_ZERO_NUMBER = predicateWithMessage((value) => isNumber(value) && value !== 0, "a non-zero number");
var LogAxis = class extends NumberAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new LogScale());
    this.min = NaN;
    this.max = NaN;
  }
  normaliseDataDomain(d) {
    const { min, max } = this;
    const { extent: extent2, clipped } = normalisedExtentWithMetadata(d, min, max);
    const isInverted = extent2[0] > extent2[1];
    const crossesZero = extent2[0] < 0 && extent2[1] > 0;
    const hasZeroExtent = extent2[0] === 0 && extent2[1] === 0;
    const invalidDomain = isInverted || crossesZero || hasZeroExtent;
    if (invalidDomain) {
      d = [];
      if (crossesZero) {
        Logger.warn(
          `the data domain crosses zero, the chart data cannot be rendered. See log axis documentation for more information.`
        );
      } else if (hasZeroExtent) {
        Logger.warn(`the data domain has 0 extent, no data is rendered.`);
      }
    }
    if (extent2[0] === 0) {
      extent2[0] = 1;
    }
    if (extent2[1] === 0) {
      extent2[1] = -1;
    }
    return { domain: extent2, clipped };
  }
  set base(value) {
    this.scale.base = value;
  }
  get base() {
    return this.scale.base;
  }
};
LogAxis.className = "LogAxis";
LogAxis.type = "log";
__decorateClass([
  Validate(AND(NUMBER_OR_NAN, NON_ZERO_NUMBER, LESS_THAN("max"))),
  Default(NaN)
], LogAxis.prototype, "min", 2);
__decorateClass([
  Validate(AND(NUMBER_OR_NAN, NON_ZERO_NUMBER, GREATER_THAN("min"))),
  Default(NaN)
], LogAxis.prototype, "max", 2);
var MAX_SPACING2 = OR(AND(NUMBER.restrict({ min: 1 }), GREATER_THAN("minSpacing")), NAN);
var TimeAxisTick = class extends AxisTick {
  constructor() {
    super(...arguments);
    this.maxSpacing = NaN;
  }
};
__decorateClass([
  Validate(MAX_SPACING2),
  Default(NaN)
], TimeAxisTick.prototype, "maxSpacing", 2);
var TimeAxis = class extends CartesianAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new TimeScale());
    this.datumFormat = "%m/%d/%y, %H:%M:%S";
    this.min = void 0;
    this.max = void 0;
    const { scale: scale2 } = this;
    this.refreshScale();
    this.datumFormatter = scale2.tickFormat({
      specifier: this.datumFormat
    });
  }
  normaliseDataDomain(d) {
    var _a;
    let { min, max } = this;
    let clipped = false;
    if (typeof min === "number") {
      min = new Date(min);
    }
    if (typeof max === "number") {
      max = new Date(max);
    }
    if (d.length > 2) {
      d = ((_a = extent(d)) != null ? _a : [0, 1e3]).map((x) => new Date(x));
    }
    if (min instanceof Date) {
      clipped || (clipped = min > d[0]);
      d = [min, d[1]];
    }
    if (max instanceof Date) {
      clipped || (clipped = max < d[1]);
      d = [d[0], max];
    }
    if (d[0] > d[1]) {
      d = [];
    }
    return { domain: d, clipped };
  }
  createTick() {
    return new TimeAxisTick();
  }
  onLabelFormatChange(ticks, format2) {
    if (format2) {
      super.onLabelFormatChange(ticks, format2);
    } else {
      this.labelFormatter = this.scale.tickFormat({ ticks });
    }
  }
  formatDatum(datum) {
    var _a;
    return (_a = this.moduleCtx.callbackCache.call(this.datumFormatter, datum)) != null ? _a : String(datum);
  }
  calculatePadding(_min, _max, reverse) {
    return reverse ? [1, 0] : [0, 1];
  }
};
TimeAxis.className = "TimeAxis";
TimeAxis.type = "time";
__decorateClass([
  Validate(AND(DATE_OR_DATETIME_MS, LESS_THAN("max")), { optional: true })
], TimeAxis.prototype, "min", 2);
__decorateClass([
  Validate(AND(DATE_OR_DATETIME_MS, GREATER_THAN("min")), { optional: true })
], TimeAxis.prototype, "max", 2);
var AXIS_CONSTRUCTORS = {
  [NumberAxis.type]: NumberAxis,
  [CategoryAxis.type]: CategoryAxis,
  [TimeAxis.type]: TimeAxis,
  [GroupedCategoryAxis.type]: GroupedCategoryAxis,
  [LogAxis.type]: LogAxis
};
function registerAxis(axisType, ctor) {
  AXIS_CONSTRUCTORS[axisType] = ctor;
}
function getAxis(axisType, moduleCtx) {
  const axisConstructor = AXIS_CONSTRUCTORS[axisType];
  if (axisConstructor) {
    return new axisConstructor(moduleCtx);
  }
  throw new Error(`AG Charts - unknown axis type: ${axisType}`);
}
var AXIS_TYPES = {
  has(axisType) {
    return Object.hasOwn(AXIS_CONSTRUCTORS, axisType);
  },
  get axesTypes() {
    return Object.keys(AXIS_CONSTRUCTORS);
  }
};
var AXIS_THEME_TEMPLATES = {};
function registerAxisThemeTemplate(axisType, theme) {
  AXIS_THEME_TEMPLATES[axisType] = theme;
}
function getAxisThemeTemplate(axisType) {
  var _a;
  return (_a = AXIS_THEME_TEMPLATES[axisType]) != null ? _a : {};
}
var EXPECTED_ENTERPRISE_MODULES = [
  { type: "root", optionsKey: "animation", chartTypes: ["cartesian", "polar", "hierarchy"] },
  {
    type: "root",
    optionsKey: "background",
    chartTypes: ["cartesian", "polar", "hierarchy"],
    optionsInnerKey: "image"
  },
  { type: "root", optionsKey: "contextMenu", chartTypes: ["cartesian", "polar", "hierarchy"] },
  { type: "root", optionsKey: "zoom", chartTypes: ["cartesian"] },
  {
    type: "legend",
    optionsKey: "gradientLegend",
    chartTypes: ["cartesian", "polar", "hierarchy"],
    identifier: "gradient"
  },
  { type: "axis", optionsKey: "axes[]", chartTypes: ["polar"], identifier: "angle-category" },
  { type: "axis", optionsKey: "axes[]", chartTypes: ["polar"], identifier: "angle-number" },
  { type: "axis", optionsKey: "axes[]", chartTypes: ["polar"], identifier: "radius-category" },
  { type: "axis", optionsKey: "axes[]", chartTypes: ["polar"], identifier: "radius-number" },
  { type: "axis-option", optionsKey: "crosshair", chartTypes: ["cartesian"] },
  { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "box-plot" },
  { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "bullet" },
  { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "heatmap" },
  { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "nightingale" },
  { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "radar-area" },
  { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "radar-line" },
  { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "radial-bar" },
  { type: "series", optionsKey: "series[]", chartTypes: ["polar"], identifier: "radial-column" },
  { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "range-area" },
  { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "range-bar" },
  { type: "series", optionsKey: "series[]", chartTypes: ["hierarchy"], identifier: "sunburst" },
  { type: "series", optionsKey: "series[]", chartTypes: ["hierarchy"], identifier: "treemap" },
  { type: "series", optionsKey: "series[]", chartTypes: ["cartesian"], identifier: "waterfall" },
  { type: "series-option", optionsKey: "errorBar", chartTypes: ["cartesian"], identifier: "error-bars" }
];
function isEnterpriseSeriesType(type) {
  return EXPECTED_ENTERPRISE_MODULES.some((s) => s.type === "series" && s.identifier === type);
}
function getEnterpriseSeriesChartTypes(type) {
  var _a;
  return (_a = EXPECTED_ENTERPRISE_MODULES.find((s) => s.type === "series" && s.identifier === type)) == null ? void 0 : _a.chartTypes;
}
function isEnterpriseSeriesTypeLoaded(type) {
  var _a, _b;
  return ((_b = (_a = EXPECTED_ENTERPRISE_MODULES.find((s) => s.type === "series" && s.identifier === type)) == null ? void 0 : _a.useCount) != null ? _b : 0) > 0;
}
function isEnterpriseCartesian(seriesType) {
  var _a;
  const type = (_a = getEnterpriseSeriesChartTypes(seriesType)) == null ? void 0 : _a.find((v) => v === "cartesian");
  return type === "cartesian";
}
function isEnterprisePolar(seriesType) {
  var _a;
  const type = (_a = getEnterpriseSeriesChartTypes(seriesType)) == null ? void 0 : _a.find((v) => v === "polar");
  return type === "polar";
}
function isEnterpriseHierarchy(seriesType) {
  var _a;
  const type = (_a = getEnterpriseSeriesChartTypes(seriesType)) == null ? void 0 : _a.find((v) => v === "hierarchy");
  return type === "hierarchy";
}
function verifyIfModuleExpected(module2) {
  var _a;
  if (module2.packageType !== "enterprise") {
    throw new Error("AG Charts - internal configuration error, only enterprise modules need verification.");
  }
  const stub = EXPECTED_ENTERPRISE_MODULES.find((s) => {
    return s.type === module2.type && s.optionsKey === module2.optionsKey && s.identifier === module2.identifier && module2.chartTypes.every((t) => s.chartTypes.includes(t));
  });
  if (stub) {
    (_a = stub.useCount) != null ? _a : stub.useCount = 0;
    stub.useCount++;
  }
  return stub != null;
}
function getUnusedExpectedModules() {
  return EXPECTED_ENTERPRISE_MODULES.filter(({ useCount }) => useCount == null || useCount === 0);
}
var LEGEND_FACTORIES = {
  category: Legend
};
var LEGEND_KEYS = {
  category: "legend"
};
function registerLegend(type, key, ctr, theme) {
  LEGEND_FACTORIES[type] = ctr;
  LEGEND_KEYS[type] = key;
  LEGEND_THEME_TEMPLATES[key] = theme;
}
var LEGEND_THEME_TEMPLATES = {};
function getLegendThemeTemplates() {
  return LEGEND_THEME_TEMPLATES;
}
function getLegendKeys() {
  return LEGEND_KEYS;
}
var Background = class extends BaseModuleInstance {
  constructor(ctx) {
    var _a;
    super();
    this.node = new Group({
      name: "background",
      zIndex: 0
      /* SERIES_BACKGROUND_ZINDEX */
    });
    this.rectNode = new Rect();
    this.visible = true;
    this.fill = "white";
    this.image = void 0;
    this.node.appendChild(this.rectNode);
    (_a = ctx.scene.root) == null ? void 0 : _a.appendChild(this.node);
    this.destroyFns.push(
      () => {
        var _a2;
        return (_a2 = ctx.scene.root) == null ? void 0 : _a2.removeChild(this.node);
      },
      ctx.layoutService.addListener("layout-complete", (e) => this.onLayoutComplete(e))
    );
  }
  onLayoutComplete(e) {
    const { width, height } = e.chart;
    this.rectNode.width = width;
    this.rectNode.height = height;
  }
};
__decorateClass([
  Validate(BOOLEAN),
  ProxyPropertyOnWrite("node", "visible")
], Background.prototype, "visible", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true }),
  ProxyPropertyOnWrite("rectNode", "fill")
], Background.prototype, "fill", 2);
var BackgroundModule = {
  type: "root",
  optionsKey: "background",
  packageType: "community",
  chartTypes: ["cartesian", "polar", "hierarchy"],
  instanceConstructor: Background
};
var NavigatorHandle = class {
  set fill(value) {
    this.rh.fill = value;
  }
  get fill() {
    return this.rh.fill;
  }
  set stroke(value) {
    this.rh.stroke = value;
  }
  get stroke() {
    return this.rh.stroke;
  }
  set strokeWidth(value) {
    this.rh.strokeWidth = value;
  }
  get strokeWidth() {
    return this.rh.strokeWidth;
  }
  set width(value) {
    this.rh.width = value;
  }
  get width() {
    return this.rh.width;
  }
  set height(value) {
    this.rh.height = value;
  }
  get height() {
    return this.rh.height;
  }
  set gripLineGap(value) {
    this.rh.gripLineGap = value;
  }
  get gripLineGap() {
    return this.rh.gripLineGap;
  }
  set gripLineLength(value) {
    this.rh.gripLineLength = value;
  }
  get gripLineLength() {
    return this.rh.gripLineLength;
  }
  constructor(rangeHandle) {
    this.rh = rangeHandle;
  }
};
var NavigatorMask = class {
  set fill(value) {
    this.rm.fill = value;
  }
  get fill() {
    return this.rm.fill;
  }
  set stroke(value) {
    this.rm.stroke = value;
  }
  get stroke() {
    return this.rm.stroke;
  }
  set strokeWidth(value) {
    this.rm.strokeWidth = value;
  }
  get strokeWidth() {
    return this.rm.strokeWidth;
  }
  set fillOpacity(value) {
    this.rm.fillOpacity = value;
  }
  get fillOpacity() {
    return this.rm.fillOpacity;
  }
  constructor(rangeMask) {
    this.rm = rangeMask;
  }
};
var RangeHandle = class extends Path {
  constructor() {
    super(...arguments);
    this._fill = "#f2f2f2";
    this._stroke = "#999999";
    this._strokeWidth = 1;
    this._lineCap = "square";
    this._centerX = 0;
    this._centerY = 0;
    this._width = 8;
    this._gripLineGap = 2;
    this._gripLineLength = 8;
    this._height = 16;
  }
  set centerX(value) {
    if (this._centerX !== value) {
      this._centerX = value;
      this.dirtyPath = true;
    }
  }
  get centerX() {
    return this._centerX;
  }
  set centerY(value) {
    if (this._centerY !== value) {
      this._centerY = value;
      this.dirtyPath = true;
    }
  }
  get centerY() {
    return this._centerY;
  }
  set width(value) {
    if (this._width !== value) {
      this._width = value;
      this.dirtyPath = true;
    }
  }
  get width() {
    return this._width;
  }
  set gripLineGap(value) {
    if (this._gripLineGap !== value) {
      this._gripLineGap = value;
      this.dirtyPath = true;
    }
  }
  get gripLineGap() {
    return this._gripLineGap;
  }
  set gripLineLength(value) {
    if (this._gripLineLength !== value) {
      this._gripLineLength = value;
      this.dirtyPath = true;
    }
  }
  get gripLineLength() {
    return this._gripLineLength;
  }
  set height(value) {
    if (this._height !== value) {
      this._height = value;
      this.dirtyPath = true;
    }
  }
  get height() {
    return this._height;
  }
  computeBBox() {
    const { centerX, centerY, width, height } = this;
    const x = centerX - width / 2;
    const y = centerY - height / 2;
    return new BBox(x, y, width, height);
  }
  isPointInPath(x, y) {
    const point = this.transformPoint(x, y);
    const bbox = this.computeBBox();
    return bbox.containsPoint(point.x, point.y);
  }
  updatePath() {
    const { path, centerX, centerY, width, height } = this;
    path.clear();
    const x = centerX - width / 2;
    const y = centerY - height / 2;
    const ax = this.align(x);
    const ay = this.align(y);
    const axw = ax + this.align(x, width);
    const ayh = ay + this.align(y, height);
    path.moveTo(ax, ay);
    path.lineTo(axw, ay);
    path.lineTo(axw, ayh);
    path.lineTo(ax, ayh);
    path.lineTo(ax, ay);
    const dx = this.gripLineGap / 2;
    const dy = this.gripLineLength / 2;
    path.moveTo(this.align(centerX - dx), this.align(centerY - dy));
    path.lineTo(this.align(centerX - dx), this.align(centerY + dy));
    path.moveTo(this.align(centerX + dx), this.align(centerY - dy));
    path.lineTo(this.align(centerX + dx), this.align(centerY + dy));
  }
};
RangeHandle.className = "RangeHandle";
__decorateClass([
  Validate(COLOR_STRING)
], RangeHandle.prototype, "_fill", 2);
__decorateClass([
  Validate(COLOR_STRING)
], RangeHandle.prototype, "_stroke", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], RangeHandle.prototype, "_strokeWidth", 2);
__decorateClass([
  Validate(LINE_CAP)
], RangeHandle.prototype, "_lineCap", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], RangeHandle.prototype, "_width", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], RangeHandle.prototype, "_gripLineGap", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], RangeHandle.prototype, "_gripLineLength", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], RangeHandle.prototype, "_height", 2);
function markDirtyOnChange(newValue, oldValue) {
  if (newValue !== oldValue) {
    this.dirtyPath = true;
  }
}
var RangeMask = class extends Path {
  constructor() {
    super(...arguments);
    this.x = 0;
    this.y = 0;
    this.width = 200;
    this.height = 30;
    this.minRange = 0.05;
    this._min = 0;
    this._max = 1;
  }
  set min(value) {
    var _a;
    value = clamp2(0, value, this.max - this.minRange);
    if (this._min !== value && !isNaN(value)) {
      this._min = value;
      this.dirtyPath = true;
      (_a = this.onRangeChange) == null ? void 0 : _a.call(this);
    }
  }
  get min() {
    return this._min;
  }
  set max(value) {
    var _a;
    value = clamp2(this.min + this.minRange, value, 1);
    if (this._max !== value && !isNaN(value)) {
      this._max = value;
      this.dirtyPath = true;
      (_a = this.onRangeChange) == null ? void 0 : _a.call(this);
    }
  }
  get max() {
    return this._max;
  }
  computeBBox() {
    const { x, y, width, height } = this;
    return new BBox(x, y, width, height);
  }
  computeVisibleRangeBBox() {
    const { x, y, width, height, min, max } = this;
    const minX = x + width * min;
    const maxX = x + width * max;
    return new BBox(minX, y, maxX - minX, height);
  }
  updatePath() {
    const { path, x, y, width, height, min, max } = this;
    path.clear();
    const ax = this.align(x);
    const ay = this.align(y);
    const axw = ax + this.align(x, width);
    const ayh = ay + this.align(y, height);
    path.moveTo(ax, ay);
    path.lineTo(axw, ay);
    path.lineTo(axw, ayh);
    path.lineTo(ax, ayh);
    path.lineTo(ax, ay);
    const minX = this.align(x + width * min);
    const maxX = this.align(x + width * max);
    path.moveTo(minX, ay);
    path.lineTo(minX, ayh);
    path.lineTo(maxX, ayh);
    path.lineTo(maxX, ay);
    path.lineTo(minX, ay);
  }
};
RangeMask.className = "RangeMask";
__decorateClass([
  ActionOnSet({ changeValue: markDirtyOnChange }),
  Validate(POSITIVE_NUMBER)
], RangeMask.prototype, "x", 2);
__decorateClass([
  ActionOnSet({ changeValue: markDirtyOnChange }),
  Validate(POSITIVE_NUMBER)
], RangeMask.prototype, "y", 2);
__decorateClass([
  ActionOnSet({ changeValue: markDirtyOnChange }),
  Validate(POSITIVE_NUMBER)
], RangeMask.prototype, "width", 2);
__decorateClass([
  ActionOnSet({ changeValue: markDirtyOnChange }),
  Validate(POSITIVE_NUMBER)
], RangeMask.prototype, "height", 2);
__decorateClass([
  Validate(NUMBER)
], RangeMask.prototype, "_min", 2);
__decorateClass([
  Validate(NUMBER)
], RangeMask.prototype, "_max", 2);
var _RangeSelector = class _RangeSelector2 extends Group {
  constructor() {
    super({ name: "rangeSelectorGroup" });
    this.minHandle = new RangeHandle();
    this.maxHandle = new RangeHandle();
    this.mask = (() => {
      const { x, y, width, height, min, max } = _RangeSelector2.defaults;
      const mask = new RangeMask();
      mask.x = x;
      mask.y = y;
      mask.width = width;
      mask.height = height;
      mask.min = min;
      mask.max = max;
      const { minHandle, maxHandle } = this;
      minHandle.centerX = x;
      maxHandle.centerX = x + width;
      minHandle.centerY = maxHandle.centerY = y + height / 2;
      this.append([mask, minHandle, maxHandle]);
      mask.onRangeChange = () => {
        var _a;
        this.updateHandles();
        (_a = this.onRangeChange) == null ? void 0 : _a.call(this);
      };
      return mask;
    })();
    this._x = _RangeSelector2.defaults.x;
    this._y = _RangeSelector2.defaults.y;
    this._width = _RangeSelector2.defaults.width;
    this._height = _RangeSelector2.defaults.height;
    this._min = _RangeSelector2.defaults.min;
    this._max = _RangeSelector2.defaults.max;
    this.isContainerNode = true;
  }
  set x(value) {
    this.mask.x = value;
    this.updateHandles();
  }
  get x() {
    return this.mask.x;
  }
  set y(value) {
    this.mask.y = value;
    this.updateHandles();
  }
  get y() {
    return this.mask.y;
  }
  set width(value) {
    this.mask.width = value;
    this.updateHandles();
  }
  get width() {
    return this.mask.width;
  }
  set height(value) {
    this.mask.height = value;
    this.updateHandles();
  }
  get height() {
    return this.mask.height;
  }
  set min(value) {
    this.mask.min = value;
  }
  get min() {
    return this.mask.min;
  }
  set max(value) {
    this.mask.max = value;
  }
  get max() {
    return this.mask.max;
  }
  updateHandles() {
    const { minHandle, maxHandle, x, y, width, height, mask } = this;
    minHandle.centerX = x + width * mask.min;
    maxHandle.centerX = x + width * mask.max;
    minHandle.centerY = maxHandle.centerY = y + height / 2;
  }
  computeBBox() {
    return this.mask.computeBBox();
  }
  computeVisibleRangeBBox() {
    return this.mask.computeVisibleRangeBBox();
  }
  render(renderCtx) {
    const { ctx, forceRender, stats } = renderCtx;
    if (this.dirty === 0 && !forceRender) {
      if (stats)
        stats.nodesSkipped++;
      return;
    }
    this.computeTransformMatrix();
    this.matrix.toContext(ctx);
    const { mask, minHandle, maxHandle } = this;
    [mask, minHandle, maxHandle].forEach((child) => {
      if (child.visible && (forceRender || child.dirty > 0)) {
        ctx.save();
        child.render(__spreadProps(__spreadValues({}, renderCtx), { ctx, forceRender }));
        ctx.restore();
      }
    });
    this.markClean({ force: true });
    if (stats)
      stats.nodesRendered++;
  }
};
_RangeSelector.className = "Range";
_RangeSelector.defaults = {
  x: 0,
  y: 0,
  width: 200,
  height: 30,
  min: 0,
  max: 1
};
var RangeSelector = _RangeSelector;
var Navigator = class extends BaseModuleInstance {
  constructor(ctx) {
    var _a;
    super();
    this.ctx = ctx;
    this.rs = new RangeSelector();
    this.mask = new NavigatorMask(this.rs.mask);
    this.minHandle = new NavigatorHandle(this.rs.minHandle);
    this.maxHandle = new NavigatorHandle(this.rs.maxHandle);
    this.minHandleDragging = false;
    this.maxHandleDragging = false;
    this.panHandleOffset = NaN;
    this.enabled = false;
    this.margin = 10;
    this._visible = true;
    this.rs.onRangeChange = () => ctx.zoomManager.updateZoom("navigator", {
      x: { min: this.rs.min, max: this.rs.max },
      y: { min: 0, max: 1 }
    });
    (_a = ctx.scene.root) == null ? void 0 : _a.appendChild(this.rs);
    const interactionOpts = { bypassPause: ["animation"] };
    this.destroyFns.push(
      ctx.interactionManager.addListener("drag-start", (event) => this.onDragStart(event), interactionOpts),
      ctx.interactionManager.addListener("drag", (event) => this.onDrag(event), interactionOpts),
      ctx.interactionManager.addListener("hover", (event) => this.onDrag(event), interactionOpts),
      ctx.interactionManager.addListener("drag-end", () => this.onDragStop(), interactionOpts),
      ctx.layoutService.addListener("before-series", (event) => this.layout(event)),
      ctx.layoutService.addListener("layout-complete", (event) => this.layoutComplete(event)),
      () => {
        var _a2;
        return (_a2 = ctx.scene.root) == null ? void 0 : _a2.removeChild(this.rs);
      },
      () => this.ctx.zoomManager.updateZoom("navigator")
    );
    this.updateGroupVisibility();
  }
  set width(value) {
    this.rs.width = value;
  }
  get width() {
    return this.rs.width;
  }
  set height(value) {
    this.rs.height = value;
  }
  get height() {
    return this.rs.height;
  }
  set min(value) {
    this.rs.min = value;
  }
  get min() {
    return this.rs.min;
  }
  set max(value) {
    this.rs.max = value;
  }
  get max() {
    return this.rs.max;
  }
  set visible(value) {
    this._visible = value;
    this.updateGroupVisibility();
  }
  get visible() {
    return this._visible;
  }
  updateGroupVisibility() {
    const visible = this.enabled && this.visible;
    this.rs.visible = visible;
    if (visible) {
      this.ctx.zoomManager.updateZoom("navigator", {
        x: { min: this.rs.min, max: this.rs.max },
        y: { min: 0, max: 1 }
      });
    } else {
      this.ctx.zoomManager.updateZoom("navigator");
    }
  }
  layout({ shrinkRect }) {
    if (this.enabled) {
      const navigatorTotalHeight = this.rs.height + this.margin;
      shrinkRect.shrink(navigatorTotalHeight, "bottom");
      this.rs.y = shrinkRect.y + shrinkRect.height + this.margin;
    }
    return { shrinkRect };
  }
  layoutComplete({ series: { rect, visible } }) {
    if (this.enabled && visible) {
      this.rs.x = rect.x;
      this.rs.width = rect.width;
    }
    this.visible = visible;
  }
  onDragStart(offset4) {
    if (!this.enabled) {
      return;
    }
    const { offsetX, offsetY } = offset4;
    const { rs } = this;
    const { minHandle, maxHandle, x, width, min } = rs;
    const visibleRange = rs.computeVisibleRangeBBox();
    if (!(this.minHandleDragging || this.maxHandleDragging)) {
      if (minHandle.containsPoint(offsetX, offsetY)) {
        this.minHandleDragging = true;
      } else if (maxHandle.containsPoint(offsetX, offsetY)) {
        this.maxHandleDragging = true;
      } else if (visibleRange.containsPoint(offsetX, offsetY)) {
        this.panHandleOffset = (offsetX - x) / width - min;
      }
    }
  }
  onDrag(offset4) {
    if (!this.enabled) {
      return;
    }
    const { rs, panHandleOffset } = this;
    const { x, y, width, height, minHandle, maxHandle } = rs;
    const { offsetX, offsetY } = offset4;
    const minX = x + width * rs.min;
    const maxX = x + width * rs.max;
    const visibleRange = new BBox(minX, y, maxX - minX, height);
    const getRatio = () => Math.min(Math.max((offsetX - x) / width, 0), 1);
    if (minHandle.containsPoint(offsetX, offsetY) || maxHandle.containsPoint(offsetX, offsetY)) {
      this.ctx.cursorManager.updateCursor("navigator", "ew-resize");
    } else if (visibleRange.containsPoint(offsetX, offsetY)) {
      this.ctx.cursorManager.updateCursor("navigator", "grab");
    } else {
      this.ctx.cursorManager.updateCursor("navigator");
    }
    if (this.minHandleDragging) {
      rs.min = getRatio();
    } else if (this.maxHandleDragging) {
      rs.max = getRatio();
    } else if (!isNaN(panHandleOffset)) {
      const span = rs.max - rs.min;
      const min = Math.min(getRatio() - panHandleOffset, 1 - span);
      if (min <= rs.min) {
        rs.min = min;
        rs.max = rs.min + span;
      } else {
        rs.max = min + span;
        rs.min = rs.max - span;
      }
    }
  }
  onDragStop() {
    this.stopHandleDragging();
  }
  stopHandleDragging() {
    this.minHandleDragging = this.maxHandleDragging = false;
    this.panHandleOffset = NaN;
  }
};
__decorateClass([
  ActionOnSet({
    changeValue(newValue) {
      if (newValue) {
        this.min = 0;
        this.max = 1;
      }
      this.updateGroupVisibility();
    }
  }),
  Validate(BOOLEAN)
], Navigator.prototype, "enabled", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], Navigator.prototype, "margin", 2);
var NavigatorModule = {
  type: "root",
  optionsKey: "navigator",
  packageType: "community",
  chartTypes: ["cartesian"],
  instanceConstructor: Navigator,
  themeTemplate: {
    navigator: {
      enabled: false,
      height: 30,
      mask: {
        fill: "#999999",
        stroke: "#999999",
        strokeWidth: 1,
        fillOpacity: 0.2
      },
      minHandle: {
        fill: "#f2f2f2",
        stroke: "#999999",
        strokeWidth: 1,
        width: 8,
        height: 16,
        gripLineGap: 2,
        gripLineLength: 8
      },
      maxHandle: {
        fill: "#f2f2f2",
        stroke: "#999999",
        strokeWidth: 1,
        width: 8,
        height: 16,
        gripLineGap: 2,
        gripLineLength: 8
      }
    }
  }
};
var singleSeriesPaletteFactory = ({ takeColors }) => {
  const {
    fills: [fill],
    strokes: [stroke]
  } = takeColors(1);
  return { fill, stroke };
};
var markerPaletteFactory = (params) => {
  const { fill, stroke } = singleSeriesPaletteFactory(params);
  return { marker: { fill, stroke } };
};
var FONT_SIZE = {
  SMALL: 12,
  MEDIUM: 13,
  LARGE: 17
};
var FONT_WEIGHT2 = {
  NORMAL: "normal",
  BOLD: "bold",
  BOLDER: "bolder",
  LIGHTER: "lighter"
};
var BOTTOM = "bottom";
var LEFT = "left";
var TOP = "top";
var CARTESIAN_AXIS_POSITIONS = {
  BOTTOM,
  LEFT,
  TOP
};
var CATEGORY = "category";
var NUMBER2 = "number";
var TIME = "time";
var LOG = "log";
var CARTESIAN_AXIS_TYPES = {
  CATEGORY,
  NUMBER: NUMBER2,
  TIME,
  LOG
};
var ANGLE_CATEGORY = "angle-category";
var ANGLE_NUMBER = "angle-number";
var RADIUS_CATEGORY = "radius-category";
var RADIUS_NUMBER = "radius-number";
var POLAR_AXIS_TYPES = {
  ANGLE_CATEGORY,
  ANGLE_NUMBER,
  RADIUS_CATEGORY,
  RADIUS_NUMBER
};
var CIRCLE = "circle";
var TYPES = {};
var DEFAULTS = {};
var CHART_TYPES = {
  has(seriesType) {
    return Object.hasOwn(TYPES, seriesType);
  },
  isCartesian(seriesType) {
    return TYPES[seriesType] === "cartesian";
  },
  isPolar(seriesType) {
    return TYPES[seriesType] === "polar";
  },
  isHierarchy(seriesType) {
    return TYPES[seriesType] === "hierarchy";
  },
  get seriesTypes() {
    return Object.keys(TYPES);
  },
  get cartesianTypes() {
    return this.seriesTypes.filter((t) => this.isCartesian(t));
  },
  get polarTypes() {
    return this.seriesTypes.filter((t) => this.isPolar(t));
  },
  get hierarchyTypes() {
    return this.seriesTypes.filter((t) => this.isHierarchy(t));
  }
};
function registerChartSeriesType(seriesType, chartType2) {
  TYPES[seriesType] = chartType2;
}
function registerChartDefaults(chartType2, defaults) {
  var _a;
  DEFAULTS[chartType2] = jsonMerge([(_a = DEFAULTS[chartType2]) != null ? _a : {}, defaults]);
}
function getChartDefaults(chartType2) {
  var _a;
  return (_a = DEFAULTS[chartType2]) != null ? _a : {};
}
function getChartType(seriesType) {
  var _a;
  return (_a = TYPES[seriesType]) != null ? _a : "unknown";
}
function optionsType(input) {
  var _a, _b, _c;
  return (_c = (_b = (_a = input.series) == null ? void 0 : _a[0]) == null ? void 0 : _b.type) != null ? _c : "line";
}
function isAgCartesianChartOptions(input) {
  const specifiedType = optionsType(input);
  if (specifiedType == null) {
    return true;
  }
  if (specifiedType === "cartesian") {
    Logger.warnOnce(`type '${specifiedType}' is deprecated, use a series type instead`);
    return true;
  }
  return CHART_TYPES.isCartesian(specifiedType) || isEnterpriseCartesian(specifiedType);
}
function isAgHierarchyChartOptions(input) {
  const specifiedType = optionsType(input);
  if (specifiedType == null) {
    return false;
  }
  if (specifiedType === "hierarchy") {
    Logger.warnOnce(`type '${specifiedType}' is deprecated, use a series type instead`);
    return true;
  }
  return CHART_TYPES.isHierarchy(specifiedType) || isEnterpriseHierarchy(specifiedType);
}
function isAgPolarChartOptions(input) {
  const specifiedType = optionsType(input);
  if (specifiedType == null) {
    return false;
  }
  if (specifiedType === "polar") {
    Logger.warnOnce(`type '${specifiedType}' is deprecated, use a series type instead`);
    return true;
  }
  return CHART_TYPES.isPolar(specifiedType) || isEnterprisePolar(specifiedType);
}
function isSeriesOptionType(input) {
  if (input == null) {
    return false;
  }
  return CHART_TYPES.has(input);
}
function isAxisOptionType(input) {
  if (input == null) {
    return false;
  }
  return AXIS_TYPES.has(input);
}
var DEFAULT_CARTESIAN_CHART_OVERRIDES = {
  axes: [
    {
      type: CARTESIAN_AXIS_TYPES.NUMBER,
      position: CARTESIAN_AXIS_POSITIONS.LEFT
    },
    {
      type: CARTESIAN_AXIS_TYPES.CATEGORY,
      position: CARTESIAN_AXIS_POSITIONS.BOTTOM
    }
  ]
};
function swapAxes(opts) {
  var _a;
  if (!isAgCartesianChartOptions(opts)) {
    return opts;
  }
  const [axis0, axis1] = (_a = opts.axes) != null ? _a : [];
  return __spreadProps(__spreadValues({}, opts), {
    axes: [
      __spreadProps(__spreadValues({}, axis0), { position: axis1.position }),
      __spreadProps(__spreadValues({}, axis1), { position: axis0.position })
    ]
  });
}
function resolveModuleConflicts(opts) {
  var _a, _b, _c, _d;
  const conflictOverrides = {};
  for (const [source, conflicts] of MODULE_CONFLICTS.entries()) {
    if (opts[source] == null || !conflicts.length) {
      continue;
    }
    (_a = conflictOverrides[source]) != null ? _a : conflictOverrides[source] = {};
    for (const conflict of conflicts) {
      if (((_b = opts[source]) == null ? void 0 : _b.enabled) && ((_c = opts[conflict]) == null ? void 0 : _c.enabled)) {
        Logger.warnOnce(
          `the [${source}] module can not be used at the same time as [${conflict}], it will be disabled.`
        );
        conflictOverrides[source].enabled = false;
      } else {
        conflictOverrides[source].enabled = (_d = opts[source]) == null ? void 0 : _d.enabled;
      }
    }
  }
  return conflictOverrides;
}
var EXTENDS_CHART_DEFAULTS = Symbol("extends-chart-defaults");
var EXTENDS_LEGEND_DEFAULTS = Symbol("extends-legend-defaults");
var EXTENDS_LEGEND_ITEM_DEFAULTS = Symbol("extends-legend-item-defaults");
var EXTENDS_LEGEND_ITEM_MARKER_DEFAULTS = Symbol("extends-legend-item-marker-defaults");
var EXTENDS_AXES_DEFAULTS = Symbol("extends-axes-defaults");
var EXTENDS_AXES_LABEL_DEFAULTS = Symbol("extends-axes-label-defaults");
var EXTENDS_AXES_LINE_DEFAULTS = Symbol("extends-axes-line-defaults");
var EXTENDS_AXES_TICK_DEFAULTS = Symbol("extends-axes-tick-defaults");
var EXTENDS_AXES_GRID_LINE_DEFAULTS = Symbol("extends-axes-grid-line-defaults");
var EXTENDS_SERIES_DEFAULTS = Symbol("extends-series-defaults");
var EXTENDS_CARTESIAN_MARKER_DEFAULTS = Symbol("extends-cartesian-marker-defaults");
var OVERRIDE_SERIES_LABEL_DEFAULTS = Symbol("override-series-label-defaults");
var DEFAULT_FONT_FAMILY = Symbol("default-font");
var DEFAULT_LABEL_COLOUR = Symbol("default-label-colour");
var DEFAULT_INVERTED_LABEL_COLOUR = Symbol("default-inverted-label-colour");
var DEFAULT_INSIDE_SERIES_LABEL_COLOUR = Symbol("default-inside-series-label-colour");
var DEFAULT_MUTED_LABEL_COLOUR = Symbol("default-muted-label-colour");
var DEFAULT_AXIS_GRID_COLOUR = Symbol("default-axis-grid-colour");
var DEFAULT_AXIS_LINE_COLOUR = Symbol("default-axis-line-colour");
var DEFAULT_CROSS_LINES_COLOUR = Symbol("default-cross-lines-colour");
var DEFAULT_BACKGROUND_COLOUR = Symbol("default-background-colour");
var DEFAULT_SHADOW_COLOUR = Symbol("default-shadow-colour");
var DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS = Symbol(
  "default-waterfall-series-positive-colors"
);
var DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS = Symbol(
  "default-waterfall-series-negative-colors"
);
var DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS = Symbol(
  "default-waterfall-series-total-colors"
);
var DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE = Symbol(
  "default-waterfall-series-connector-line-stroke"
);
var DEFAULT_POLAR_SERIES_STROKE = Symbol("default-polar-series-stroke");
var DEFAULT_DIVERGING_SERIES_COLOUR_RANGE = Symbol(
  "default-diverging-series-colour-range"
);
var DEFAULT_HIERARCHY_FILLS = Symbol("default-hierarchy-fills");
var DEFAULT_HIERARCHY_STROKES = Symbol("default-hierarchy-strokes");
function pathMotion(groupId, subId, animationManager, paths, fns) {
  const { defaultDuration } = animationManager;
  const { addPhaseFn, updatePhaseFn, removePhaseFn } = fns;
  const animate = (phase, path, updateFn) => {
    animationManager.animate({
      id: `${groupId}_${subId}_${path.id}_${phase}`,
      groupId,
      from: 0,
      to: 1,
      ease: easeOut,
      onUpdate(ratio, preInit) {
        if (preInit && phase !== "removed")
          return;
        path.path.clear({ trackChanges: true });
        updateFn(ratio, path);
        path.checkPathDirty();
      },
      onStop() {
        if (phase !== "added")
          return;
        path.path.clear({ trackChanges: true });
        updateFn(1, path);
        path.checkPathDirty();
      },
      duration: FROM_TO_MIXINS[phase].animationDuration * defaultDuration,
      delay: FROM_TO_MIXINS[phase].animationDelay * defaultDuration
    });
  };
  for (const path of paths) {
    if (!animationManager.isSkipped()) {
      animate("removed", path, removePhaseFn);
      animate("updated", path, updatePhaseFn);
    }
    animate("added", path, addPhaseFn);
  }
}
function seriesLabelFadeInAnimation({ id }, subId, animationManager, labelSelections) {
  staticFromToMotion(id, subId, animationManager, labelSelections, { opacity: 0 }, { opacity: 1 }, LABEL_PHASE);
}
function seriesLabelFadeOutAnimation({ id }, subId, animationManager, labelSelections) {
  staticFromToMotion(id, subId, animationManager, labelSelections, { opacity: 1 }, { opacity: 0 }, LABEL_PHASE);
}
function resetLabelFn(_node) {
  return { opacity: 1 };
}
var MARKER_SHAPE = predicateWithMessage(
  (value) => isMarkerShape(value) || Object.getPrototypeOf(value) === Marker,
  `a marker shape keyword such as 'circle', 'diamond' or 'square' or an object extending the Marker class`
);
var SeriesMarker = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.shape = Circle;
    this.size = 6;
    this.fillOpacity = 1;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
  }
  getStyle() {
    const { size, fill, fillOpacity, stroke, strokeWidth, strokeOpacity } = this;
    return { size, fill, fillOpacity, stroke, strokeWidth, strokeOpacity };
  }
  getDiameter() {
    return this.size + this.strokeWidth;
  }
};
__decorateClass([
  Validate(BOOLEAN),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "enabled", 2);
__decorateClass([
  Validate(MARKER_SHAPE),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "shape", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "size", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true }),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "fill", 2);
__decorateClass([
  Validate(RATIO),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "fillOpacity", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true }),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "stroke", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "strokeOpacity", 2);
__decorateClass([
  Validate(FUNCTION, { optional: true }),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], SeriesMarker.prototype, "formatter", 2);
var SeriesTooltipInteraction = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = false;
  }
};
__decorateClass([
  Validate(BOOLEAN)
], SeriesTooltipInteraction.prototype, "enabled", 2);
var SeriesTooltip = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.interaction = new SeriesTooltipInteraction();
    this.position = new TooltipPosition();
  }
  toTooltipHtml(defaults, params) {
    if (this.renderer) {
      return toTooltipHtml(this.renderer(params), defaults);
    }
    return toTooltipHtml(defaults);
  }
};
__decorateClass([
  Validate(BOOLEAN)
], SeriesTooltip.prototype, "enabled", 2);
__decorateClass([
  Validate(BOOLEAN, { optional: true })
], SeriesTooltip.prototype, "showArrow", 2);
__decorateClass([
  Validate(FUNCTION, { optional: true })
], SeriesTooltip.prototype, "renderer", 2);
__decorateClass([
  Validate(OBJECT)
], SeriesTooltip.prototype, "interaction", 2);
__decorateClass([
  Validate(OBJECT)
], SeriesTooltip.prototype, "position", 2);
var AreaSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.xName = void 0;
    this.fill = "#c16068";
    this.fillOpacity = 1;
    this.stroke = "#874349";
    this.strokeWidth = 2;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.shadow = new DropShadow();
    this.marker = new SeriesMarker();
    this.label = new Label();
    this.tooltip = new SeriesTooltip();
    this.connectMissingData = false;
  }
};
__decorateClass([
  Validate(STRING)
], AreaSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], AreaSeriesProperties.prototype, "xName", 2);
__decorateClass([
  Validate(STRING)
], AreaSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], AreaSeriesProperties.prototype, "yName", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], AreaSeriesProperties.prototype, "normalizedTo", 2);
__decorateClass([
  Validate(COLOR_STRING)
], AreaSeriesProperties.prototype, "fill", 2);
__decorateClass([
  Validate(RATIO)
], AreaSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  Validate(COLOR_STRING)
], AreaSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], AreaSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO)
], AreaSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  Validate(LINE_DASH)
], AreaSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], AreaSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  Validate(OBJECT)
], AreaSeriesProperties.prototype, "shadow", 2);
__decorateClass([
  Validate(OBJECT)
], AreaSeriesProperties.prototype, "marker", 2);
__decorateClass([
  Validate(OBJECT)
], AreaSeriesProperties.prototype, "label", 2);
__decorateClass([
  Validate(OBJECT)
], AreaSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  Validate(BOOLEAN)
], AreaSeriesProperties.prototype, "connectMissingData", 2);
function markerFadeInAnimation({ id }, animationManager, markerSelections, status = "unknown") {
  const params = __spreadValues({}, FROM_TO_MIXINS[status]);
  staticFromToMotion(id, "markers", animationManager, markerSelections, { opacity: 0 }, { opacity: 1 }, params);
  markerSelections.forEach((s) => s.cleanup());
}
function markerScaleInAnimation({ id }, animationManager, markerSelections) {
  staticFromToMotion(
    id,
    "markers",
    animationManager,
    markerSelections,
    { scalingX: 0, scalingY: 0 },
    { scalingX: 1, scalingY: 1 }
  );
  markerSelections.forEach((s) => s.cleanup());
}
function markerSwipeScaleInAnimation({ id, nodeDataDependencies }, animationManager, markerSelections) {
  const seriesWidth = nodeDataDependencies.seriesRectWidth;
  const fromFn = (_, datum) => {
    var _a, _b;
    const x = (_b = (_a = datum.midPoint) == null ? void 0 : _a.x) != null ? _b : seriesWidth;
    const delay = clamp2(0, inverseEaseOut(x / seriesWidth), 1);
    const animationDuration = Debug.check("animationImmediateMarkerSwipeScaleIn") ? 0 : QUICK_TRANSITION;
    return { scalingX: 0, scalingY: 0, animationDelay: delay, animationDuration };
  };
  const toFn = () => {
    return { scalingX: 1, scalingY: 1 };
  };
  fromToMotion(id, "markers", animationManager, markerSelections, { fromFn, toFn });
}
function resetMarkerFn(_node) {
  return { opacity: 1, scalingX: 1, scalingY: 1 };
}
function resetMarkerPositionFn(_node, datum) {
  var _a, _b, _c, _d;
  return {
    translationX: (_b = (_a = datum.point) == null ? void 0 : _a.x) != null ? _b : NaN,
    translationY: (_d = (_c = datum.point) == null ? void 0 : _c.y) != null ? _d : NaN
  };
}
function prepareMarkerAnimation(pairMap, parentStatus) {
  const readFirstPair = (xValue, type) => {
    const val = pairMap[type][xValue];
    return Array.isArray(val) ? val[0] : val;
  };
  const markerStatus = (datum) => {
    const { xValue } = datum;
    if (pairMap.moved[xValue]) {
      return { point: readFirstPair(xValue, "moved"), status: "updated" };
    } else if (pairMap.removed[xValue]) {
      return { point: readFirstPair(xValue, "removed"), status: "removed" };
    } else if (pairMap.added[xValue]) {
      return { point: readFirstPair(xValue, "added"), status: "added" };
    }
    return { status: "unknown" };
  };
  const fromFn = (marker, datum) => {
    var _a, _b, _c, _d, _e, _f;
    const { status, point } = markerStatus(datum);
    if (status === "unknown")
      return { opacity: 0 };
    const defaults = __spreadValues({
      translationX: (_b = (_a = point == null ? void 0 : point.from) == null ? void 0 : _a.x) != null ? _b : marker.translationX,
      translationY: (_d = (_c = point == null ? void 0 : point.from) == null ? void 0 : _c.y) != null ? _d : marker.translationY,
      opacity: marker.opacity
    }, FROM_TO_MIXINS[status]);
    if (parentStatus === "added") {
      return __spreadValues(__spreadProps(__spreadValues({}, defaults), {
        opacity: 0,
        translationX: (_e = point == null ? void 0 : point.to) == null ? void 0 : _e.x,
        translationY: (_f = point == null ? void 0 : point.to) == null ? void 0 : _f.y
      }), FROM_TO_MIXINS["added"]);
    }
    if (status === "added") {
      defaults.opacity = 0;
    }
    return defaults;
  };
  const toFn = (_marker, datum) => {
    var _a, _b;
    const { status, point } = markerStatus(datum);
    if (status === "unknown")
      return { opacity: 0 };
    const defaults = __spreadValues({
      translationX: datum.point.x,
      translationY: datum.point.y,
      opacity: 1
    }, FROM_TO_MIXINS[status]);
    if (status === "removed" || parentStatus === "removed") {
      return __spreadValues(__spreadProps(__spreadValues({}, defaults), {
        translationX: (_a = point == null ? void 0 : point.to) == null ? void 0 : _a.x,
        translationY: (_b = point == null ? void 0 : point.to) == null ? void 0 : _b.y,
        opacity: 0
      }), FROM_TO_MIXINS["removed"]);
    }
    return defaults;
  };
  return { fromFn, toFn };
}
function minMax(nodeData) {
  return nodeData.reduce(
    ({ min, max }, node) => {
      if (min == null || min.point.x > node.point.x) {
        min = node;
      }
      if (max == null || max.point.x < node.point.x) {
        max = node;
      }
      return { min, max };
    },
    {}
  );
}
function intersectionOnLine(a, b, targetX) {
  const m = (b.y - a.y) / (b.x - a.x);
  const y = (targetX - a.x) * m + a.y;
  return { x: targetX, y };
}
function backfillPathPoint(results, process, skip, processFn) {
  let prevMarkerIdx = -1, nextMarkerIdx = 0;
  const toProcess = [];
  while (nextMarkerIdx < results.length) {
    if (results[nextMarkerIdx].change === process) {
      toProcess.push(results[nextMarkerIdx]);
      nextMarkerIdx++;
      continue;
    }
    if (results[nextMarkerIdx].change === skip) {
      nextMarkerIdx++;
      continue;
    }
    if (toProcess.length > 0) {
      processFn(toProcess, prevMarkerIdx, nextMarkerIdx);
      toProcess.length = 0;
    }
    prevMarkerIdx = nextMarkerIdx;
    nextMarkerIdx++;
  }
  if (toProcess.length > 0) {
    processFn(toProcess, prevMarkerIdx, nextMarkerIdx);
  }
}
function backfillPathPointData(result, splitMode) {
  backfillPathPoint(result, "out", "in", (toProcess, sIdx, eIdx) => {
    var _a, _b;
    if (sIdx === -1 && result[eIdx]) {
      toProcess.forEach((d) => d.to = result[eIdx].from);
    } else if (eIdx === result.length && result[sIdx]) {
      toProcess.forEach((d) => d.to = result[sIdx].from);
    } else if (splitMode === "intersect" && ((_a = result[sIdx]) == null ? void 0 : _a.from) && ((_b = result[eIdx]) == null ? void 0 : _b.from)) {
      toProcess.forEach((d) => d.to = intersectionOnLine(result[sIdx].from, result[eIdx].from, d.from.x));
    } else {
      toProcess.forEach((d) => d.to = d.from);
    }
  });
  backfillPathPoint(result, "in", "out", (toProcess, sIdx, eIdx) => {
    var _a, _b;
    if (sIdx === -1 && result[eIdx]) {
      toProcess.forEach((d) => d.from = result[eIdx].to);
    } else if (eIdx === result.length && result[sIdx]) {
      toProcess.forEach((d) => d.from = result[sIdx].to);
    } else if (splitMode === "intersect" && ((_a = result[sIdx]) == null ? void 0 : _a.to) && ((_b = result[eIdx]) == null ? void 0 : _b.to)) {
      toProcess.forEach((d) => d.from = intersectionOnLine(result[sIdx].to, result[eIdx].to, d.to.x));
    } else {
      toProcess.forEach((d) => d.from = d.to);
    }
  });
}
function calculatePoint(from, to, ratio) {
  const x1 = isNaN(from.x) ? to.x : from.x;
  const y1 = isNaN(from.y) ? to.y : from.y;
  const xd = to.x - from.x;
  const yd = to.y - from.y;
  const xr = isNaN(xd) ? 0 : xd * ratio;
  const yr = isNaN(yd) ? 0 : yd * ratio;
  return {
    x: x1 + xr,
    y: y1 + yr
  };
}
function renderPartialPath(pairData, ratios, path) {
  const { path: linePath } = path;
  let previousTo;
  for (const data of pairData) {
    const ratio = ratios[data.change];
    if (ratio == null)
      continue;
    const { from, to } = data;
    if (from == null || to == null)
      continue;
    const { x, y } = calculatePoint(from, to, ratio);
    if (data.moveTo === false) {
      linePath.lineTo(x, y);
    } else if (data.moveTo === true || !previousTo) {
      linePath.moveTo(x, y);
    } else if (previousTo) {
      const moveToRatio = data.moveTo === "in" ? ratio : 1 - ratio;
      const { x: midPointX, y: midPointY } = calculatePoint(previousTo, { x, y }, moveToRatio);
      linePath.lineTo(midPointX, midPointY);
      linePath.moveTo(x, y);
    }
    previousTo = { x, y };
  }
}
function pathSwipeInAnimation({ id, visible }, animationManager, paths) {
  staticFromToMotion(
    id,
    "path_properties",
    animationManager,
    paths,
    { clipScalingX: 0 },
    { clipScalingX: 1 },
    {
      start: { clipMode: "normal", visible },
      finish: { clipMode: void 0, visible }
    }
  );
}
function pathFadeInAnimation({ id }, subId, animationManager, selection) {
  staticFromToMotion(id, subId, animationManager, selection, { opacity: 0 }, { opacity: 1 }, LABEL_PHASE);
}
function pathFadeOutAnimation({ id }, subId, animationManager, selection) {
  staticFromToMotion(id, subId, animationManager, selection, { opacity: 1 }, { opacity: 0 }, LABEL_PHASE);
}
function buildResetPathFn(opts) {
  return (_node) => {
    return { opacity: opts.getOpacity(), clipScalingX: 1, clipMode: void 0 };
  };
}
function updateClipPath({ nodeDataDependencies }, path) {
  var _a, _b;
  const { seriesRectHeight: height, seriesRectWidth: width } = nodeDataDependencies;
  if (path.clipPath == null) {
    path.clipPath = new Path2D();
    path.clipScalingX = 1;
    path.clipScalingY = 1;
  }
  (_a = path.clipPath) == null ? void 0 : _a.clear({ trackChanges: true });
  (_b = path.clipPath) == null ? void 0 : _b.rect(-25, -25, toReal(width) + 50, toReal(height) + 50);
}
function isContinuousScaling(scaling) {
  return scaling.type === "continuous" || scaling.type === "log";
}
function isCategoryScaling(scaling) {
  return scaling.type === "category";
}
function areEqual(a, b) {
  return a.domain.length === b.domain.length && a.range.length === b.range.length && a.domain.every((val, index) => val === b.domain[index]) && a.range.every((val, index) => val === b.range[index]);
}
function areScalingEqual(a, b) {
  if (a === void 0 || b === void 0) {
    return a !== void 0 || b !== void 0;
  }
  if (isContinuousScaling(a) && isContinuousScaling(b)) {
    return a.type === b.type && areEqual(a, b);
  }
  if (isCategoryScaling(a) && isCategoryScaling(b)) {
    return areEqual(a, b);
  }
  return false;
}
function scale(val, scaling) {
  if (!scaling)
    return NaN;
  if (val instanceof Date) {
    val = val.getTime();
  }
  if (scaling.type === "continuous" && typeof val === "number") {
    const domainRatio = (val - scaling.domain[0]) / (scaling.domain[1] - scaling.domain[0]);
    return domainRatio * (scaling.range[1] - scaling.range[0]) + scaling.range[0];
  }
  if (scaling.type === "log" && typeof val === "number") {
    return scaling.convert(val);
  }
  const matchingIndex = scaling.domain.findIndex((d) => d === val);
  if (matchingIndex >= 0) {
    return scaling.range[matchingIndex];
  }
  return NaN;
}
function scalesChanged(newData, oldData) {
  return !areScalingEqual(newData.scales.x, oldData.scales.x) || !areScalingEqual(newData.scales.y, oldData.scales.y);
}
function closeMatch(a, b) {
  const an = Number(a);
  const bn = Number(b);
  if (!isNaN(an) && !isNaN(bn)) {
    return Math.abs(bn - an) < 0.25;
  }
  return a === b;
}
function calculateMoveTo(from = false, to = false) {
  if (from === to) {
    return !!from;
  }
  return from ? "in" : "out";
}
function pairContinuousData(newData, oldData, opts = {}) {
  var _a, _b, _c, _d;
  const { backfillSplitMode = "intersect" } = opts;
  const toNewScale = (oldDatum) => {
    var _a2, _b2;
    return {
      x: scale((_a2 = oldDatum.xValue) != null ? _a2 : NaN, newData.scales.x),
      y: scale((_b2 = oldDatum.yValue) != null ? _b2 : NaN, newData.scales.y)
    };
  };
  const toOldScale = (newDatum) => {
    var _a2, _b2;
    return {
      x: scale((_a2 = newDatum.xValue) != null ? _a2 : NaN, oldData.scales.x),
      y: scale((_b2 = newDatum.yValue) != null ? _b2 : NaN, oldData.scales.y)
    };
  };
  const result = [];
  const resultMap = {
    added: {},
    moved: {},
    removed: {}
  };
  const pairUp = (from, to, xValue, change = "move") => {
    if (from && (isNaN(from.point.x) || isNaN(from.point.y))) {
      from = to;
    }
    const resultPoint = {
      from: from == null ? void 0 : from.point,
      to: to == null ? void 0 : to.point,
      moveTo: calculateMoveTo(from == null ? void 0 : from.point.moveTo, to == null ? void 0 : to.point.moveTo),
      change
    };
    if (change === "move") {
      resultMap.moved[xValue] = resultPoint;
      oldIdx++;
      newIdx++;
    } else if (change === "in") {
      resultMap.added[xValue] = resultPoint;
      newIdx++;
    } else if (change === "out") {
      resultMap.removed[xValue] = resultPoint;
      oldIdx++;
    }
    result.push(resultPoint);
  };
  const { min: minFromNode, max: maxFromNode } = minMax(oldData.nodeData);
  const { min: minToNode, max: maxToNode } = minMax(newData.nodeData);
  let oldIdx = 0;
  let newIdx = 0;
  while (oldIdx < oldData.nodeData.length || newIdx < newData.nodeData.length) {
    const from = oldData.nodeData[oldIdx];
    const to = newData.nodeData[newIdx];
    const fromShifted = from ? toNewScale(from) : void 0;
    const toUnshifted = to ? toOldScale(to) : void 0;
    const NA = void 0;
    if (fromShifted && closeMatch(fromShifted.x, to == null ? void 0 : to.point.x)) {
      pairUp(from, to, to.xValue, "move");
    } else if (fromShifted && fromShifted.x < ((_a = minToNode == null ? void 0 : minToNode.point.x) != null ? _a : -Infinity)) {
      pairUp(from, NA, from.xValue, "out");
    } else if (fromShifted && fromShifted.x > ((_b = maxToNode == null ? void 0 : maxToNode.point.x) != null ? _b : Infinity)) {
      pairUp(from, NA, from.xValue, "out");
    } else if (toUnshifted && toUnshifted.x < ((_c = minFromNode == null ? void 0 : minFromNode.point.x) != null ? _c : -Infinity)) {
      pairUp(NA, to, to.xValue, "in");
    } else if (toUnshifted && toUnshifted.x > ((_d = maxFromNode == null ? void 0 : maxFromNode.point.x) != null ? _d : Infinity)) {
      pairUp(NA, to, to.xValue, "in");
    } else if (fromShifted && fromShifted.x < (to == null ? void 0 : to.point.x)) {
      pairUp(from, NA, from.xValue, "out");
    } else if (toUnshifted && toUnshifted.x < (from == null ? void 0 : from.point.x)) {
      pairUp(NA, to, to.xValue, "in");
    } else if (from) {
      pairUp(from, NA, from.xValue, "out");
    } else if (to) {
      pairUp(NA, to, to.xValue, "in");
    } else {
      throw new Error("Unable to process points");
    }
  }
  backfillPathPointData(result, backfillSplitMode);
  return { result, resultMap };
}
function pairCategoryData(newData, oldData, diff2, opts = {}) {
  var _a, _b, _c;
  const { backfillSplitMode = "intersect", multiDatum = false } = opts;
  const result = [];
  const resultMapSingle = {
    added: {},
    moved: {},
    removed: {}
  };
  const resultMapMulti = {
    added: {},
    moved: {},
    removed: {}
  };
  let previousResultPoint = void 0;
  let previousXValue = void 0;
  const addToResultMap = (xValue, result2) => {
    var _a2, _b2;
    const type = result2.change === "move" ? "moved" : result2.change === "in" ? "added" : "removed";
    if (multiDatum) {
      (_b2 = (_a2 = resultMapMulti[type])[xValue]) != null ? _b2 : _a2[xValue] = [];
      resultMapMulti[type][xValue].push(result2);
    } else {
      resultMapSingle[type][xValue] = result2;
    }
    previousResultPoint = result2;
    previousXValue = xValue;
  };
  let oldIndex = 0;
  let newIndex = 0;
  let isXUnordered = false;
  while (oldIndex < oldData.nodeData.length || newIndex < newData.nodeData.length) {
    const before = oldData.nodeData[oldIndex];
    const after = newData.nodeData[newIndex];
    let resultPoint;
    if ((before == null ? void 0 : before.xValue) === (after == null ? void 0 : after.xValue)) {
      resultPoint = {
        change: "move",
        moveTo: calculateMoveTo((_a = before.point.moveTo) != null ? _a : false, after.point.moveTo),
        from: before.point,
        to: after.point
      };
      addToResultMap(before.xValue, resultPoint);
      oldIndex++;
      newIndex++;
    } else if (diff2 !== void 0 && diff2.removed.indexOf(before == null ? void 0 : before.xValue) >= 0) {
      resultPoint = {
        change: "out",
        moveTo: (_b = before.point.moveTo) != null ? _b : false,
        from: before.point
      };
      addToResultMap(before.xValue, resultPoint);
      oldIndex++;
    } else if (diff2 !== void 0 && diff2.added.indexOf(after == null ? void 0 : after.xValue) >= 0) {
      resultPoint = {
        change: "in",
        moveTo: (_c = after.point.moveTo) != null ? _c : false,
        to: after.point
      };
      addToResultMap(after.xValue, resultPoint);
      newIndex++;
    } else if (multiDatum && previousResultPoint && previousXValue === (before == null ? void 0 : before.xValue)) {
      resultPoint = __spreadValues({}, previousResultPoint);
      addToResultMap(before.xValue, resultPoint);
      oldIndex++;
    } else if (multiDatum && previousResultPoint && previousXValue === (after == null ? void 0 : after.xValue)) {
      resultPoint = __spreadValues({}, previousResultPoint);
      addToResultMap(after.xValue, resultPoint);
      newIndex++;
    } else {
      isXUnordered = true;
      break;
    }
    result.push(resultPoint);
  }
  let previousX = -Infinity;
  isXUnordered || (isXUnordered = result.some((pathPoint) => {
    const { change: marker, to: { x = -Infinity } = {} } = pathPoint;
    if (marker === "out")
      return;
    const result2 = x < previousX;
    previousX = x;
    return result2;
  }));
  if (isXUnordered) {
    return { result: void 0, resultMap: void 0 };
  }
  backfillPathPointData(result, backfillSplitMode);
  if (multiDatum) {
    return { result, resultMap: resultMapMulti };
  }
  return { result, resultMap: resultMapSingle };
}
function determinePathStatus(newData, oldData) {
  let status = "updated";
  const visible = (data) => {
    return data.visible;
  };
  if (!visible(oldData) && visible(newData)) {
    status = "added";
  } else if (visible(oldData) && !visible(newData)) {
    status = "removed";
  }
  return status;
}
function prepareLinePathPropertyAnimation(status, visibleToggleMode) {
  const phase = visibleToggleMode === "none" ? "updated" : status;
  const result = {
    fromFn: (_path) => {
      let mixin;
      if (status === "removed") {
        mixin = { finish: { visible: false } };
      } else if (status === "added") {
        mixin = { start: { visible: true } };
      } else {
        mixin = {};
      }
      return __spreadValues(__spreadValues({}, FROM_TO_MIXINS[phase]), mixin);
    },
    toFn: (_path) => {
      return __spreadValues({}, FROM_TO_MIXINS[phase]);
    }
  };
  if (visibleToggleMode === "fade") {
    return {
      fromFn: (path) => {
        const opacity = status === "added" ? 0 : path.opacity;
        return __spreadValues({ opacity }, result.fromFn(path));
      },
      toFn: (path) => {
        const opacity = status === "removed" ? 0 : 1;
        return __spreadValues({ opacity }, result.toFn(path));
      }
    };
  }
  return result;
}
function prepareLinePathAnimationFns(newData, oldData, pairData, visibleToggleMode, render) {
  const status = determinePathStatus(newData, oldData);
  const removePhaseFn = (ratio, path) => {
    render(pairData, { move: 0, out: ratio }, path);
  };
  const updatePhaseFn = (ratio, path) => {
    render(pairData, { move: ratio }, path);
  };
  const addPhaseFn = (ratio, path) => {
    render(pairData, { move: 1, in: ratio }, path);
  };
  const pathProperties = prepareLinePathPropertyAnimation(status, visibleToggleMode);
  return { status, path: { addPhaseFn, updatePhaseFn, removePhaseFn }, pathProperties };
}
function prepareLinePathAnimation(newData, oldData, diff2) {
  var _a, _b;
  const isCategoryBased = ((_a = newData.scales.x) == null ? void 0 : _a.type) === "category";
  const { result: pairData, resultMap: pairMap } = isCategoryBased ? pairCategoryData(newData, oldData, diff2) : pairContinuousData(newData, oldData);
  let status = "updated";
  if (oldData.visible && !newData.visible) {
    status = "removed";
  } else if (!oldData.visible && newData.visible) {
    status = "added";
  }
  if (pairData === void 0 || pairMap === void 0) {
    return;
  }
  const hasMotion = ((_b = diff2 == null ? void 0 : diff2.changed) != null ? _b : true) || scalesChanged(newData, oldData);
  const pathFns = prepareLinePathAnimationFns(newData, oldData, pairData, "fade", renderPartialPath);
  const marker = prepareMarkerAnimation(pairMap, status);
  return __spreadProps(__spreadValues({}, pathFns), { marker, hasMotion });
}
var AreaSeriesTag = /* @__PURE__ */ ((AreaSeriesTag2) => {
  AreaSeriesTag2[AreaSeriesTag2["Fill"] = 0] = "Fill";
  AreaSeriesTag2[AreaSeriesTag2["Stroke"] = 1] = "Stroke";
  AreaSeriesTag2[AreaSeriesTag2["Marker"] = 2] = "Marker";
  AreaSeriesTag2[AreaSeriesTag2["Label"] = 3] = "Label";
  return AreaSeriesTag2;
})(AreaSeriesTag || {});
function splitFillPoints(context) {
  const { points } = context.fillData;
  return { top: points.slice(0, points.length / 2), bottom: points.slice(points.length / 2).reverse() };
}
function prepPoints(key, ctx, points) {
  return {
    scales: ctx.scales,
    nodeData: points[key],
    visible: ctx.visible
  };
}
function pairFillCategoryData(newData, oldData, diff2) {
  const oldPoints = splitFillPoints(oldData);
  const newPoints = splitFillPoints(newData);
  const pairOpts = { multiDatum: true };
  return {
    top: pairCategoryData(
      prepPoints("top", newData, newPoints),
      prepPoints("top", oldData, oldPoints),
      diff2,
      pairOpts
    ),
    bottom: pairCategoryData(
      prepPoints("bottom", newData, newPoints),
      prepPoints("bottom", oldData, oldPoints),
      diff2,
      pairOpts
    )
  };
}
function pairFillContinuousData(newData, oldData) {
  const oldPoints = splitFillPoints(oldData);
  const newPoints = splitFillPoints(newData);
  return {
    top: pairContinuousData(prepPoints("top", newData, newPoints), prepPoints("top", oldData, oldPoints)),
    bottom: pairContinuousData(prepPoints("bottom", newData, newPoints), prepPoints("bottom", oldData, oldPoints))
  };
}
function prepareAreaPathAnimation(newData, oldData, diff2) {
  var _a;
  const isCategoryBased = ((_a = newData.scales.x) == null ? void 0 : _a.type) === "category";
  let status = "updated";
  if (oldData.visible && !newData.visible) {
    status = "removed";
  } else if (!oldData.visible && newData.visible) {
    status = "added";
  }
  const prepareMarkerPairs = () => {
    if (isCategoryBased) {
      return pairCategoryData(newData, oldData, diff2, { backfillSplitMode: "static", multiDatum: true });
    }
    return pairContinuousData(newData, oldData, { backfillSplitMode: "static" });
  };
  const prepareFillPairs = () => {
    if (isCategoryBased) {
      return pairFillCategoryData(newData, oldData, diff2);
    }
    return pairFillContinuousData(newData, oldData);
  };
  const { resultMap: markerPairMap } = prepareMarkerPairs();
  const { top, bottom } = prepareFillPairs();
  if (markerPairMap === void 0 || top.result === void 0 || bottom.result === void 0) {
    return;
  }
  const pairData = [...top.result, ...bottom.result.reverse()];
  const fill = prepareLinePathAnimationFns(newData, oldData, pairData, "none", renderPartialPath);
  const marker = prepareMarkerAnimation(markerPairMap, status);
  return { fill, marker };
}
var _AreaSeries = class _AreaSeries2 extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pathsPerSeries: 2,
      pathsZIndexSubOrderOffset: [0, 1e3],
      hasMarkers: true,
      markerSelectionGarbageCollection: false,
      pickModes: [
        1,
        0
        /* EXACT_SHAPE_MATCH */
      ],
      animationResetFns: {
        path: buildResetPathFn({ getOpacity: () => this.getOpacity() }),
        label: resetLabelFn,
        marker: (node, datum) => __spreadValues(__spreadValues({}, resetMarkerFn(node)), resetMarkerPositionFn(node, datum))
      }
    });
    this.properties = new AreaSeriesProperties();
  }
  processData(dataController) {
    return __async(this, null, function* () {
      if (this.data == null || !this.properties.isValid()) {
        return;
      }
      const { data, visible, seriesGrouping: { groupIndex = this.id, stackCount = 1 } = {} } = this;
      const { xKey, yKey, connectMissingData, normalizedTo } = this.properties;
      const animationEnabled = !this.ctx.animationManager.isSkipped();
      const { isContinuousX, isContinuousY } = this.isContinuous();
      const ids = [
        `area-stack-${groupIndex}-yValues`,
        `area-stack-${groupIndex}-yValues-trailing`,
        `area-stack-${groupIndex}-yValues-prev`,
        `area-stack-${groupIndex}-yValues-trailing-prev`,
        `area-stack-${groupIndex}-yValues-marker`
      ];
      const extraProps = [];
      if (isDefined(normalizedTo)) {
        extraProps.push(normaliseGroupTo(this, [ids[0], ids[1], ids[4]], normalizedTo, "range"));
        extraProps.push(normaliseGroupTo(this, [ids[2], ids[3]], normalizedTo, "range"));
      }
      if (!isContinuousX && animationEnabled && this.processedData) {
        extraProps.push(diff(this.processedData));
      }
      if (animationEnabled) {
        extraProps.push(animationValidation(this));
      }
      const common = { invalidValue: null };
      if (connectMissingData && stackCount > 1) {
        common.invalidValue = 0;
      }
      if (!visible) {
        common.forceValue = 0;
      }
      yield this.requestDataModel(dataController, data, {
        props: [
          keyProperty(this, xKey, isContinuousX, { id: "xValue" }),
          valueProperty(this, yKey, isContinuousY, __spreadValues({ id: `yValueRaw` }, common)),
          ...groupAccumulativeValueProperty(this, yKey, isContinuousY, "window", "current", __spreadProps(__spreadValues({
            id: `yValueEnd`
          }, common), {
            groupId: ids[0]
          })),
          ...groupAccumulativeValueProperty(this, yKey, isContinuousY, "window-trailing", "current", __spreadProps(__spreadValues({
            id: `yValueStart`
          }, common), {
            groupId: ids[1]
          })),
          ...groupAccumulativeValueProperty(this, yKey, isContinuousY, "window", "last", __spreadProps(__spreadValues({
            id: `yValuePreviousEnd`
          }, common), {
            groupId: ids[2]
          })),
          ...groupAccumulativeValueProperty(this, yKey, isContinuousY, "window-trailing", "last", __spreadProps(__spreadValues({
            id: `yValuePreviousStart`
          }, common), {
            groupId: ids[3]
          })),
          ...groupAccumulativeValueProperty(this, yKey, isContinuousY, "normal", "current", __spreadProps(__spreadValues({
            id: `yValueCumulative`
          }, common), {
            groupId: ids[4]
          })),
          ...extraProps
        ],
        groupByKeys: true,
        groupByData: false
      });
      this.animationState.transition("updateData");
    });
  }
  getSeriesDomain(direction) {
    const { processedData, dataModel, axes } = this;
    if (!processedData || !dataModel || processedData.data.length === 0)
      return [];
    const xAxis = axes[
      "x"
      /* X */
    ];
    const yAxis = axes[
      "y"
      /* Y */
    ];
    const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
    const keys = dataModel.getDomain(this, `xValue`, "key", processedData);
    const yExtent = dataModel.getDomain(this, `yValueEnd`, "value", processedData);
    if (direction === "x") {
      if ((keyDef == null ? void 0 : keyDef.def.type) === "key" && keyDef.def.valueType === "category") {
        return keys;
      }
      return fixNumericExtent(extent(keys), xAxis);
    } else if (yAxis instanceof LogAxis || yAxis instanceof TimeAxis) {
      return fixNumericExtent(yExtent, yAxis);
    } else {
      const fixedYExtent = [yExtent[0] > 0 ? 0 : yExtent[0], yExtent[1] < 0 ? 0 : yExtent[1]];
      return fixNumericExtent(fixedYExtent, yAxis);
    }
  }
  createNodeData() {
    return __async(this, null, function* () {
      var _a;
      const { axes, data, processedData: { data: groupedData } = {}, dataModel } = this;
      const xAxis = axes[
        "x"
        /* X */
      ];
      const yAxis = axes[
        "y"
        /* Y */
      ];
      if (!xAxis || !yAxis || !data || !dataModel || !this.properties.isValid()) {
        return [];
      }
      const {
        yKey,
        xKey,
        marker,
        label,
        fill: seriesFill,
        stroke: seriesStroke,
        connectMissingData
      } = this.properties;
      const { scale: xScale } = xAxis;
      const { scale: yScale } = yAxis;
      const continuousY = ContinuousScale.is(yScale);
      const xOffset = ((_a = xScale.bandwidth) != null ? _a : 0) / 2;
      const defs = dataModel.resolveProcessedDataDefsByIds(this, [
        `yValueStart`,
        `yValueEnd`,
        `yValueRaw`,
        `yValuePreviousStart`,
        `yValuePreviousEnd`,
        `yValueCumulative`
      ]);
      const createMovePoint = (plainPoint) => {
        const _a2 = plainPoint, { point } = _a2, stroke = __objRest(_a2, ["point"]);
        return __spreadProps(__spreadValues({}, stroke), { point: __spreadProps(__spreadValues({}, point), { moveTo: true }) });
      };
      const createPathCoordinates = (xValue, lastYEnd, yEnd) => {
        const x = xScale.convert(xValue) + xOffset;
        const prevYCoordinate = yScale.convert(lastYEnd);
        const currYCoordinate = yScale.convert(yEnd);
        return [
          { point: { x, y: currYCoordinate }, yValue: yEnd, xValue },
          { point: { x, y: prevYCoordinate }, yValue: lastYEnd, xValue }
        ];
      };
      const createMarkerCoordinate = (xDatum, yEnd, rawYDatum) => {
        let currY;
        if (isDefined(this.properties.normalizedTo) ? continuousY && isContinuous(rawYDatum) : !isNaN(rawYDatum)) {
          currY = yEnd;
        }
        return {
          x: xScale.convert(xDatum) + xOffset,
          y: yScale.convert(currY),
          size: marker.size
        };
      };
      const itemId = yKey;
      const labelData = [];
      const markerData = [];
      const context = {
        itemId,
        fillData: { itemId, points: [] },
        strokeData: { itemId, points: [] },
        labelData,
        nodeData: markerData,
        scales: __superGet(_AreaSeries2.prototype, this, "calculateScaling").call(this),
        visible: this.visible
      };
      const fillPoints = context.fillData.points;
      const fillPhantomPoints = [];
      const strokePoints = context.strokeData.points;
      let datumIdx = -1;
      let lastXDatum;
      let lastYDatum = -Infinity;
      groupedData == null ? void 0 : groupedData.forEach((datumGroup) => {
        const {
          keys,
          keys: [xDatum],
          datum: datumArray,
          values: valuesArray
        } = datumGroup;
        valuesArray.forEach((values, valueIdx) => {
          var _a2, _b, _c;
          datumIdx++;
          const seriesDatum = datumArray[valueIdx];
          const dataValues = dataModel.resolveProcessedDataDefsValues(defs, { keys, values });
          const { yValueRaw: yDatum, yValueCumulative } = dataValues;
          let { yValueStart, yValueEnd, yValuePreviousStart, yValuePreviousEnd } = dataValues;
          const validPoint = yDatum != null;
          const point = createMarkerCoordinate(xDatum, +yValueCumulative, yDatum);
          if (validPoint && marker) {
            markerData.push({
              index: datumIdx,
              series: this,
              itemId,
              datum: seriesDatum,
              midPoint: { x: point.x, y: point.y },
              cumulativeValue: yValueEnd,
              yValue: yDatum,
              xValue: xDatum,
              yKey,
              xKey,
              point,
              fill: (_a2 = marker.fill) != null ? _a2 : seriesFill,
              stroke: (_b = marker.stroke) != null ? _b : seriesStroke,
              strokeWidth: (_c = marker.strokeWidth) != null ? _c : this.getStrokeWidth(this.properties.strokeWidth)
            });
          }
          if (validPoint && label) {
            const labelText = this.getLabelText(
              label,
              {
                value: yDatum,
                datum: seriesDatum,
                xKey,
                yKey,
                xName: this.properties.xName,
                yName: this.properties.yName
              },
              (value) => isNumber2(value) ? value.toFixed(2) : String(value)
            );
            labelData.push({
              index: datumIdx,
              series: this,
              itemId: yKey,
              datum: seriesDatum,
              x: point.x,
              y: point.y,
              label: labelText ? {
                text: labelText,
                fontStyle: label.fontStyle,
                fontWeight: label.fontWeight,
                fontSize: label.fontSize,
                fontFamily: label.fontFamily,
                textAlign: "center",
                textBaseline: "bottom",
                fill: label.color
              } : void 0
            });
          }
          const xValid = lastXDatum != null && xDatum != null;
          const yValid = lastYDatum != null && validPoint;
          if (!yValid) {
            yValueStart = yValueStart != null ? yValueStart : 0;
            yValueEnd = yValueStart != null ? yValueStart : 0;
            yValuePreviousStart = yValuePreviousStart != null ? yValuePreviousStart : 0;
            yValuePreviousEnd = yValuePreviousStart != null ? yValuePreviousStart : 0;
          }
          const [prevTop, prevBottom] = createPathCoordinates(lastXDatum, yValuePreviousStart, yValuePreviousEnd);
          const [top, bottom] = createPathCoordinates(xDatum, yValueStart, yValueEnd);
          if (xValid && (!connectMissingData || yValid)) {
            fillPoints.push(prevTop);
            fillPhantomPoints.push(prevBottom);
            fillPoints.push(top);
            fillPhantomPoints.push(bottom);
          }
          if (yValid && datumIdx > 0) {
            strokePoints.push(createMovePoint(prevTop));
            strokePoints.push(top);
          }
          lastXDatum = xDatum;
          lastYDatum = yDatum;
        });
      });
      if (strokePoints.length > 0) {
        strokePoints[0] = createMovePoint(strokePoints[0]);
      }
      fillPhantomPoints.reverse();
      fillPoints.push(...fillPhantomPoints);
      return [context];
    });
  }
  isPathOrSelectionDirty() {
    return this.properties.marker.isDirty();
  }
  markerFactory() {
    const { shape } = this.properties.marker;
    const MarkerShape = getMarker(shape);
    return new MarkerShape();
  }
  updatePathNodes(opts) {
    return __async(this, null, function* () {
      const { opacity, visible, animationEnabled } = opts;
      const [fill, stroke] = opts.paths;
      const strokeWidth = this.getStrokeWidth(this.properties.strokeWidth);
      stroke.setProperties({
        tag: 1,
        fill: void 0,
        lineJoin: stroke.lineCap = "round",
        pointerEvents: 1,
        stroke: this.properties.stroke,
        strokeWidth,
        strokeOpacity: this.properties.strokeOpacity,
        lineDash: this.properties.lineDash,
        lineDashOffset: this.properties.lineDashOffset,
        opacity,
        visible
      });
      fill.setProperties({
        tag: 0,
        stroke: void 0,
        lineJoin: "round",
        pointerEvents: 1,
        fill: this.properties.fill,
        fillOpacity: this.properties.fillOpacity,
        lineDash: this.properties.lineDash,
        lineDashOffset: this.properties.lineDashOffset,
        strokeOpacity: this.properties.strokeOpacity,
        fillShadow: this.properties.shadow,
        opacity,
        visible: visible || animationEnabled,
        strokeWidth
      });
      updateClipPath(this, stroke);
      updateClipPath(this, fill);
    });
  }
  updatePaths(opts) {
    return __async(this, null, function* () {
      this.updateAreaPaths([opts.paths], [opts.contextData]);
    });
  }
  updateAreaPaths(paths, contextData) {
    this.updateFillPath(paths, contextData);
    this.updateStrokePath(paths, contextData);
  }
  updateFillPath(paths, contextData) {
    contextData.forEach(({ fillData }, contextDataIndex) => {
      const [fill] = paths[contextDataIndex];
      const { path: fillPath } = fill;
      fillPath.clear({ trackChanges: true });
      for (const { point } of fillData.points) {
        if (point.moveTo) {
          fillPath.moveTo(point.x, point.y);
        } else {
          fillPath.lineTo(point.x, point.y);
        }
      }
      fillPath.closePath();
      fill.checkPathDirty();
    });
  }
  updateStrokePath(paths, contextData) {
    contextData.forEach(({ strokeData }, contextDataIndex) => {
      const [, stroke] = paths[contextDataIndex];
      const { path: strokePath } = stroke;
      strokePath.clear({ trackChanges: true });
      for (const { point } of strokeData.points) {
        if (point.moveTo) {
          strokePath.moveTo(point.x, point.y);
        } else {
          strokePath.lineTo(point.x, point.y);
        }
      }
      stroke.checkPathDirty();
    });
  }
  updateMarkerSelection(opts) {
    return __async(this, null, function* () {
      const { nodeData, markerSelection } = opts;
      if (this.properties.marker.isDirty()) {
        markerSelection.clear();
        markerSelection.cleanup();
      }
      return markerSelection.update(this.properties.marker.enabled ? nodeData : []);
    });
  }
  updateMarkerNodes(opts) {
    return __async(this, null, function* () {
      const { markerSelection, isHighlight: highlighted } = opts;
      const { xKey, yKey, marker, fill, stroke, strokeWidth, fillOpacity, strokeOpacity, highlightStyle } = this.properties;
      const baseStyle = mergeDefaults(highlighted && highlightStyle.item, marker.getStyle(), {
        fill,
        stroke,
        strokeWidth,
        fillOpacity,
        strokeOpacity
      });
      markerSelection.each((node, datum) => {
        this.updateMarkerStyle(node, marker, { datum, highlighted, xKey, yKey }, baseStyle);
      });
      if (!highlighted) {
        this.properties.marker.markClean();
      }
    });
  }
  updateLabelSelection(opts) {
    return __async(this, null, function* () {
      const { labelData, labelSelection } = opts;
      return labelSelection.update(labelData, (text) => {
        text.tag = 3;
      });
    });
  }
  updateLabelNodes(opts) {
    return __async(this, null, function* () {
      const { labelSelection } = opts;
      const { enabled: labelEnabled, fontStyle, fontWeight, fontSize, fontFamily, color } = this.properties.label;
      labelSelection.each((text, datum) => {
        const { x, y, label } = datum;
        if (label && labelEnabled && this.visible) {
          text.fontStyle = fontStyle;
          text.fontWeight = fontWeight;
          text.fontSize = fontSize;
          text.fontFamily = fontFamily;
          text.textAlign = label.textAlign;
          text.textBaseline = label.textBaseline;
          text.text = label.text;
          text.x = x;
          text.y = y - 10;
          text.fill = color;
          text.visible = true;
        } else {
          text.visible = false;
        }
      });
    });
  }
  getTooltipHtml(nodeDatum) {
    const { id: seriesId, axes, dataModel } = this;
    const { xKey, xName, yName, tooltip, marker } = this.properties;
    const { yKey, xValue, yValue, datum } = nodeDatum;
    const xAxis = axes[
      "x"
      /* X */
    ];
    const yAxis = axes[
      "y"
      /* Y */
    ];
    if (!this.properties.isValid() || !(xAxis && yAxis && isNumber2(yValue)) || !dataModel) {
      return "";
    }
    const xString = xAxis.formatDatum(xValue);
    const yString = yAxis.formatDatum(yValue);
    const title = sanitizeHtml(yName);
    const content = sanitizeHtml(xString + ": " + yString);
    const baseStyle = mergeDefaults({ fill: this.properties.fill }, marker.getStyle(), {
      stroke: this.properties.stroke,
      strokeWidth: this.properties.strokeWidth
    });
    const { fill: color } = this.getMarkerStyle(
      marker,
      { datum: nodeDatum, xKey, yKey, highlighted: false },
      baseStyle
    );
    return tooltip.toTooltipHtml(
      { title, content, backgroundColor: color },
      {
        datum,
        xKey,
        xName,
        yKey,
        yName,
        color,
        title,
        seriesId
      }
    );
  }
  getLegendData(legendType) {
    var _a, _b, _c, _d, _e, _f;
    if (!((_a = this.data) == null ? void 0 : _a.length) || !this.properties.isValid() || legendType !== "category") {
      return [];
    }
    const { yKey, yName, fill, stroke, fillOpacity, strokeOpacity, strokeWidth, lineDash, marker, visible } = this.properties;
    return [
      {
        legendType,
        id: this.id,
        itemId: yKey,
        seriesId: this.id,
        enabled: visible,
        label: {
          text: yName != null ? yName : yKey
        },
        marker: {
          shape: marker.shape,
          fill: (_b = marker.fill) != null ? _b : fill,
          stroke: (_c = marker.stroke) != null ? _c : stroke,
          fillOpacity: (_d = marker.fillOpacity) != null ? _d : fillOpacity,
          strokeOpacity: (_e = marker.strokeOpacity) != null ? _e : strokeOpacity,
          strokeWidth: (_f = marker.strokeWidth) != null ? _f : 0,
          enabled: marker.enabled || strokeWidth <= 0
        },
        line: {
          stroke,
          strokeOpacity,
          strokeWidth,
          lineDash
        }
      }
    ];
  }
  animateEmptyUpdateReady(animationData) {
    const { markerSelections, labelSelections, contextData, paths } = animationData;
    const { animationManager } = this.ctx;
    this.updateAreaPaths(paths, contextData);
    pathSwipeInAnimation(this, animationManager, paths.flat());
    resetMotion(markerSelections, resetMarkerPositionFn);
    markerSwipeScaleInAnimation(this, animationManager, markerSelections);
    seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelections);
  }
  animateReadyResize(animationData) {
    const { contextData, paths } = animationData;
    this.updateAreaPaths(paths, contextData);
    super.animateReadyResize(animationData);
  }
  animateWaitingUpdateReady(animationData) {
    var _a, _b;
    const { animationManager } = this.ctx;
    const { markerSelections, labelSelections, contextData, paths, previousContextData } = animationData;
    super.resetAllAnimation(animationData);
    if (contextData.length === 0 || !previousContextData || previousContextData.length === 0) {
      animationManager.skipCurrentBatch();
      this.updateAreaPaths(paths, contextData);
      return;
    }
    const [[fill, stroke]] = paths;
    const [newData] = contextData;
    const [oldData] = previousContextData;
    const fns = prepareAreaPathAnimation(newData, oldData, (_b = (_a = this.processedData) == null ? void 0 : _a.reduced) == null ? void 0 : _b.diff);
    if (fns === void 0) {
      animationManager.skipCurrentBatch();
      this.updateAreaPaths(paths, contextData);
      return;
    }
    fromToMotion(this.id, "marker_update", animationManager, markerSelections, fns.marker);
    fromToMotion(this.id, "fill_path_properties", animationManager, [fill], fns.fill.pathProperties);
    pathMotion(this.id, "fill_path_update", animationManager, [fill], fns.fill.path);
    this.updateStrokePath(paths, contextData);
    pathFadeInAnimation(this, "stroke", animationManager, [stroke]);
    seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelections);
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  nodeFactory() {
    return new Group();
  }
};
_AreaSeries.className = "AreaSeries";
_AreaSeries.type = "area";
var AreaSeries = _AreaSeries;
var AreaSeriesModule = {
  type: "series",
  optionsKey: "series[]",
  packageType: "community",
  chartTypes: ["cartesian"],
  identifier: "area",
  instanceConstructor: AreaSeries,
  stackable: true,
  seriesDefaults: DEFAULT_CARTESIAN_CHART_OVERRIDES,
  themeTemplate: {
    __extends__: EXTENDS_SERIES_DEFAULTS,
    nodeClickRange: "nearest",
    tooltip: {
      position: {
        type: "node"
      }
    },
    fillOpacity: 0.8,
    strokeOpacity: 1,
    strokeWidth: 0,
    lineDash: [0],
    lineDashOffset: 0,
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    },
    marker: {
      __extends__: EXTENDS_CARTESIAN_MARKER_DEFAULTS,
      enabled: false,
      fillOpacity: 1,
      strokeOpacity: 1,
      strokeWidth: 0
    },
    label: {
      enabled: false,
      fontStyle: void 0,
      fontWeight: void 0,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_LABEL_COLOUR,
      formatter: void 0
    }
  },
  paletteFactory: (params) => {
    const { marker } = markerPaletteFactory(params);
    return {
      fill: marker.fill,
      stroke: marker.stroke,
      marker
    };
  }
};
var AbstractBarSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.direction = "vertical";
  }
};
__decorateClass([
  Validate(DIRECTION)
], AbstractBarSeriesProperties.prototype, "direction", 2);
var AbstractBarSeries = class extends CartesianSeries {
  getBandScalePadding() {
    return { inner: 0.2, outer: 0.1 };
  }
  shouldFlipXY() {
    return !this.isVertical();
  }
  isVertical() {
    return this.properties.direction === "vertical";
  }
  getBarDirection() {
    return this.shouldFlipXY() ? "x" : "y";
  }
  getCategoryDirection() {
    return this.shouldFlipXY() ? "y" : "x";
  }
  getValueAxis() {
    const direction = this.getBarDirection();
    return this.axes[direction];
  }
  getCategoryAxis() {
    const direction = this.getCategoryDirection();
    return this.axes[direction];
  }
};
var BarSeriesLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.placement = "inside";
  }
};
__decorateClass([
  Validate(PLACEMENT)
], BarSeriesLabel.prototype, "placement", 2);
var BarSeriesProperties = class extends AbstractBarSeriesProperties {
  constructor() {
    super(...arguments);
    this.fill = "#c16068";
    this.fillOpacity = 1;
    this.stroke = "#874349";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.shadow = new DropShadow();
    this.label = new BarSeriesLabel();
    this.tooltip = new SeriesTooltip();
  }
};
__decorateClass([
  Validate(STRING)
], BarSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BarSeriesProperties.prototype, "xName", 2);
__decorateClass([
  Validate(STRING)
], BarSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BarSeriesProperties.prototype, "yName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BarSeriesProperties.prototype, "stackGroup", 2);
__decorateClass([
  Validate(NUMBER, { optional: true })
], BarSeriesProperties.prototype, "normalizedTo", 2);
__decorateClass([
  Validate(COLOR_STRING)
], BarSeriesProperties.prototype, "fill", 2);
__decorateClass([
  Validate(RATIO)
], BarSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  Validate(COLOR_STRING)
], BarSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], BarSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO)
], BarSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  Validate(LINE_DASH)
], BarSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], BarSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], BarSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  Validate(FUNCTION, { optional: true })
], BarSeriesProperties.prototype, "formatter", 2);
__decorateClass([
  Validate(OBJECT, { optional: true })
], BarSeriesProperties.prototype, "shadow", 2);
__decorateClass([
  Validate(OBJECT)
], BarSeriesProperties.prototype, "label", 2);
__decorateClass([
  Validate(OBJECT)
], BarSeriesProperties.prototype, "tooltip", 2);
function updateRect({ rect, config }) {
  const {
    crisp = true,
    fill,
    stroke,
    strokeWidth,
    fillOpacity,
    strokeOpacity,
    lineDash,
    lineDashOffset,
    fillShadow,
    cornerRadius = 0,
    topLeftCornerRadius,
    topRightCornerRadius,
    bottomRightCornerRadius,
    bottomLeftCornerRadius,
    cornerRadiusBbox,
    visible = true
  } = config;
  rect.crisp = crisp;
  rect.fill = fill;
  rect.stroke = stroke;
  rect.strokeWidth = strokeWidth;
  rect.fillOpacity = fillOpacity;
  rect.strokeOpacity = strokeOpacity;
  rect.lineDash = lineDash;
  rect.lineDashOffset = lineDashOffset;
  rect.fillShadow = fillShadow;
  rect.topLeftCornerRadius = topLeftCornerRadius ? cornerRadius : 0;
  rect.topRightCornerRadius = topRightCornerRadius ? cornerRadius : 0;
  rect.bottomRightCornerRadius = bottomRightCornerRadius ? cornerRadius : 0;
  rect.bottomLeftCornerRadius = bottomLeftCornerRadius ? cornerRadius : 0;
  rect.cornerRadiusBbox = cornerRadiusBbox;
  rect.visible = visible;
}
function getRectConfig(_a) {
  var _b = _a, {
    datum,
    isHighlighted,
    style,
    highlightStyle,
    formatter,
    seriesId,
    ctx: { callbackCache }
  } = _b, opts = __objRest(_b, [
    "datum",
    "isHighlighted",
    "style",
    "highlightStyle",
    "formatter",
    "seriesId",
    "ctx"
  ]);
  var _a2, _b2, _c, _d, _e, _f;
  const { fill, fillOpacity, stroke, strokeWidth } = mergeDefaults(isHighlighted && highlightStyle, style);
  const {
    strokeOpacity,
    fillShadow,
    lineDash,
    lineDashOffset,
    cornerRadius = 0,
    topLeftCornerRadius = true,
    topRightCornerRadius = true,
    bottomRightCornerRadius = true,
    bottomLeftCornerRadius = true,
    cornerRadiusBbox
  } = style;
  let format2;
  if (formatter) {
    format2 = callbackCache.call(formatter, __spreadValues({
      datum: datum.datum,
      xKey: datum.xKey,
      fill,
      stroke,
      strokeWidth,
      cornerRadius,
      highlighted: isHighlighted,
      seriesId
    }, opts));
  }
  return {
    fill: (_a2 = format2 == null ? void 0 : format2.fill) != null ? _a2 : fill,
    stroke: (_b2 = format2 == null ? void 0 : format2.stroke) != null ? _b2 : stroke,
    strokeWidth: (_c = format2 == null ? void 0 : format2.strokeWidth) != null ? _c : strokeWidth,
    fillOpacity: (_d = format2 == null ? void 0 : format2.fillOpacity) != null ? _d : fillOpacity,
    strokeOpacity: (_e = format2 == null ? void 0 : format2.strokeOpacity) != null ? _e : strokeOpacity,
    lineDash,
    lineDashOffset,
    fillShadow,
    // @ts-expect-error Remove once corner radius is officially added
    cornerRadius: (_f = format2 == null ? void 0 : format2.cornerRadius) != null ? _f : cornerRadius,
    topLeftCornerRadius,
    topRightCornerRadius,
    bottomRightCornerRadius,
    bottomLeftCornerRadius,
    cornerRadiusBbox
  };
}
function checkCrisp(visibleRange = []) {
  const [visibleMin, visibleMax] = visibleRange;
  const isZoomed = visibleMin !== 0 || visibleMax !== 1;
  return !isZoomed;
}
function collapsedStartingBarPosition(isVertical, axes) {
  const { startingX, startingY } = getStartingValues(isVertical, axes);
  const isDatumNegative = (datum) => {
    var _a;
    return isNegative((_a = datum["yValue"]) != null ? _a : 0);
  };
  const calculate = (datum, prevDatum) => {
    let x = isVertical ? datum.x : startingX;
    let y = isVertical ? startingY : datum.y;
    let width = isVertical ? datum.width : 0;
    let height = isVertical ? 0 : datum.height;
    if (prevDatum && (isNaN(x) || isNaN(y))) {
      ({ x, y } = prevDatum);
      width = isVertical ? prevDatum.width : 0;
      height = isVertical ? 0 : prevDatum.height;
      if (isVertical && !isDatumNegative(prevDatum)) {
        y += prevDatum.height;
      } else if (!isVertical && isDatumNegative(prevDatum)) {
        x += prevDatum.width;
      }
    }
    return { x, y, width, height };
  };
  return { isVertical, calculate };
}
function midpointStartingBarPosition(isVertical) {
  return {
    isVertical,
    calculate: (datum) => {
      return {
        x: isVertical ? datum.x : datum.x + datum.width / 2,
        y: isVertical ? datum.y + datum.height / 2 : datum.y,
        width: isVertical ? datum.width : 0,
        height: isVertical ? 0 : datum.height
      };
    }
  };
}
function prepareBarAnimationFunctions(initPos) {
  const isRemoved = (datum) => datum == null || isNaN(datum.x) || isNaN(datum.y);
  const fromFn = (rect, datum, status) => {
    if (status === "updated" && isRemoved(datum)) {
      status = "removed";
    } else if (status === "updated" && isRemoved(rect.previousDatum)) {
      status = "added";
    }
    let source = { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
    if (status === "unknown" || status === "added") {
      source = initPos.calculate(datum, rect.previousDatum);
    }
    return __spreadValues(__spreadValues({}, source), FROM_TO_MIXINS[status]);
  };
  const toFn = (rect, datum, status) => {
    if (status === "removed" || isRemoved(datum)) {
      return initPos.calculate(datum, rect.previousDatum);
    }
    return { x: datum.x, y: datum.y, width: datum.width, height: datum.height };
  };
  return { toFn, fromFn };
}
function getStartingValues(isVertical, axes) {
  const axis = axes[
    isVertical ? "y" : "x"
    /* X */
  ];
  let startingX = Infinity;
  let startingY = 0;
  if (!axis) {
    return { startingX, startingY };
  }
  if (isVertical) {
    startingY = axis.scale.convert(ContinuousScale.is(axis.scale) ? 0 : Math.max(...axis.range));
  } else {
    startingX = axis.scale.convert(ContinuousScale.is(axis.scale) ? 0 : Math.min(...axis.range));
  }
  return { startingX, startingY };
}
function resetBarSelectionsFn(_node, { x, y, width, height }) {
  return { x, y, width, height };
}
function updateLabelNode(textNode, label, labelDatum) {
  if (label.enabled && labelDatum) {
    const { x, y, text, textAlign, textBaseline } = labelDatum;
    const { color: fill, fontStyle, fontWeight, fontSize, fontFamily } = label;
    textNode.setProperties({
      visible: true,
      x,
      y,
      text,
      fill,
      fontStyle,
      fontWeight,
      fontSize,
      fontFamily,
      textAlign,
      textBaseline
    });
  } else {
    textNode.visible = false;
  }
}
function adjustLabelPlacement({
  isPositive,
  isVertical,
  placement,
  padding = 0,
  rect
}) {
  let x = rect.x + rect.width / 2;
  let y = rect.y + rect.height / 2;
  let textAlign = "center";
  let textBaseline = "middle";
  switch (placement) {
    case "start": {
      if (isVertical) {
        y = isPositive ? rect.y + rect.height + padding : rect.y - padding;
        textBaseline = isPositive ? "top" : "bottom";
      } else {
        x = isPositive ? rect.x - padding : rect.x + rect.width + padding;
        textAlign = isPositive ? "start" : "end";
      }
      break;
    }
    case "outside":
    case "end": {
      if (isVertical) {
        y = isPositive ? rect.y - padding : rect.y + rect.height + padding;
        textBaseline = isPositive ? "bottom" : "top";
      } else {
        x = isPositive ? rect.x + rect.width + padding : rect.x - padding;
        textAlign = isPositive ? "start" : "end";
      }
      break;
    }
  }
  return { x, y, textAlign, textBaseline };
}
var _BarSeries = class _BarSeries2 extends AbstractBarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [
        0
        /* EXACT_SHAPE_MATCH */
      ],
      pathsPerSeries: 0,
      hasHighlightedLabels: true,
      datumSelectionGarbageCollection: false,
      animationResetFns: {
        datum: resetBarSelectionsFn,
        label: resetLabelFn
      }
    });
    this.properties = new BarSeriesProperties();
    this.groupScale = new BandScale();
    this.smallestDataInterval = void 0;
  }
  resolveKeyDirection(direction) {
    if (this.getBarDirection() === "x") {
      if (direction === "x") {
        return "y";
      }
      return "x";
    }
    return direction;
  }
  processData(dataController) {
    return __async(this, null, function* () {
      var _a, _b, _c, _d;
      if (!this.properties.isValid() || !this.data) {
        return;
      }
      const { seriesGrouping: { groupIndex = this.id } = {}, data = [] } = this;
      const { xKey, yKey, normalizedTo } = this.properties;
      const animationEnabled = !this.ctx.animationManager.isSkipped();
      const normalizedToAbs = Math.abs(normalizedTo != null ? normalizedTo : NaN);
      const isContinuousX = ContinuousScale.is((_a = this.getCategoryAxis()) == null ? void 0 : _a.scale);
      const isContinuousY = ContinuousScale.is((_b = this.getValueAxis()) == null ? void 0 : _b.scale);
      const stackGroupName = `bar-stack-${groupIndex}-yValues`;
      const stackGroupTrailingName = `${stackGroupName}-trailing`;
      const normaliseTo = normalizedToAbs && isFinite(normalizedToAbs) ? normalizedToAbs : void 0;
      const extraProps = [];
      if (normaliseTo) {
        extraProps.push(normaliseGroupTo(this, [stackGroupName, stackGroupTrailingName], normaliseTo, "range"));
      }
      if (animationEnabled && this.processedData) {
        extraProps.push(diff(this.processedData));
      }
      if (animationEnabled) {
        extraProps.push(animationValidation(this));
      }
      const visibleProps = !this.visible ? { forceValue: 0 } : {};
      const { processedData } = yield this.requestDataModel(dataController, data, {
        props: [
          keyProperty(this, xKey, isContinuousX, { id: "xValue" }),
          valueProperty(this, yKey, isContinuousY, __spreadValues({ id: `yValue-raw`, invalidValue: null }, visibleProps)),
          ...groupAccumulativeValueProperty(this, yKey, isContinuousY, "normal", "current", __spreadValues({
            id: `yValue-end`,
            rangeId: `yValue-range`,
            invalidValue: null,
            missingValue: 0,
            groupId: stackGroupName,
            separateNegative: true
          }, visibleProps)),
          ...groupAccumulativeValueProperty(this, yKey, isContinuousY, "trailing", "current", __spreadValues({
            id: `yValue-start`,
            invalidValue: null,
            missingValue: 0,
            groupId: stackGroupTrailingName,
            separateNegative: true
          }, visibleProps)),
          ...isContinuousX ? [SMALLEST_KEY_INTERVAL] : [],
          ...extraProps
        ],
        groupByKeys: true,
        groupByData: false
      });
      this.smallestDataInterval = {
        x: (_d = (_c = processedData.reduced) == null ? void 0 : _c.smallestKeyInterval) != null ? _d : Infinity,
        y: Infinity
      };
      this.animationState.transition("updateData");
    });
  }
  getSeriesDomain(direction) {
    var _a;
    const { processedData, dataModel } = this;
    if (!processedData || !dataModel || processedData.data.length === 0)
      return [];
    const { reduced: { [SMALLEST_KEY_INTERVAL.property]: smallestX } = {} } = processedData;
    const categoryAxis = this.getCategoryAxis();
    const valueAxis = this.getValueAxis();
    const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
    const keys = dataModel.getDomain(this, `xValue`, "key", processedData);
    const yExtent = dataModel.getDomain(this, `yValue-end`, "value", processedData);
    if (direction === this.getCategoryDirection()) {
      if ((keyDef == null ? void 0 : keyDef.def.type) === "key" && (keyDef == null ? void 0 : keyDef.def.valueType) === "category") {
        return keys;
      }
      const scalePadding = smallestX != null && isFinite(smallestX) ? smallestX : 0;
      const keysExtent = (_a = extent(keys)) != null ? _a : [NaN, NaN];
      const isReversed = categoryAxis == null ? void 0 : categoryAxis.isReversed();
      if (direction === "y") {
        const d02 = keysExtent[0] + (isReversed ? 0 : -scalePadding);
        const d12 = keysExtent[1] + (isReversed ? scalePadding : 0);
        return fixNumericExtent([d02, d12], categoryAxis);
      }
      const d0 = keysExtent[0] + (isReversed ? -scalePadding : 0);
      const d1 = keysExtent[1] + (isReversed ? 0 : scalePadding);
      return fixNumericExtent([d0, d1], categoryAxis);
    } else if (this.getValueAxis() instanceof LogAxis) {
      return fixNumericExtent(yExtent, valueAxis);
    } else {
      const fixedYExtent = [yExtent[0] > 0 ? 0 : yExtent[0], yExtent[1] < 0 ? 0 : yExtent[1]];
      return fixNumericExtent(fixedYExtent, valueAxis);
    }
  }
  createNodeData() {
    return __async(this, null, function* () {
      const { dataModel } = this;
      const xAxis = this.getCategoryAxis();
      const yAxis = this.getValueAxis();
      if (!(dataModel && xAxis && yAxis && this.properties.isValid())) {
        return [];
      }
      const xScale = xAxis.scale;
      const yScale = yAxis.scale;
      const {
        groupScale,
        processedData,
        smallestDataInterval,
        ctx: { seriesStateManager }
      } = this;
      const { xKey, yKey, xName, yName, fill, stroke, strokeWidth, cornerRadius, legendItemName, label } = this.properties;
      const yReversed = yAxis.isReversed();
      const xBandWidth = ContinuousScale.is(xScale) ? xScale.calcBandwidth(smallestDataInterval == null ? void 0 : smallestDataInterval.x) : xScale.bandwidth;
      const domain = [];
      const { index: groupIndex, visibleGroupCount } = seriesStateManager.getVisiblePeerGroupIndex(this);
      for (let groupIdx = 0; groupIdx < visibleGroupCount; groupIdx++) {
        domain.push(String(groupIdx));
      }
      groupScale.domain = domain;
      groupScale.range = [0, xBandWidth != null ? xBandWidth : 0];
      if (xAxis instanceof CategoryAxis) {
        groupScale.paddingInner = xAxis.groupPaddingInner;
      } else if (xAxis instanceof GroupedCategoryAxis) {
        groupScale.padding = 0.1;
      } else {
        groupScale.padding = 0;
      }
      groupScale.round = groupScale.padding !== 0;
      const barWidth = groupScale.bandwidth >= 1 ? (
        // Pixel-rounded value for low-volume bar charts.
        groupScale.bandwidth
      ) : (
        // Handle high-volume bar charts gracefully.
        groupScale.rawBandwidth
      );
      const xIndex = dataModel.resolveProcessedDataIndexById(this, `xValue`).index;
      const yRawIndex = dataModel.resolveProcessedDataIndexById(this, `yValue-raw`).index;
      const yStartIndex = dataModel.resolveProcessedDataIndexById(this, `yValue-start`).index;
      const yEndIndex = dataModel.resolveProcessedDataIndexById(this, `yValue-end`).index;
      const yRangeIndex = dataModel.resolveProcessedDataDefById(this, `yValue-range`).index;
      const animationEnabled = !this.ctx.animationManager.isSkipped();
      const contexts = [];
      processedData == null ? void 0 : processedData.data.forEach(({ keys, datum: seriesDatum, values, aggValues }) => {
        values.forEach((value, contextIndex) => {
          var _a, _b;
          (_a = contexts[contextIndex]) != null ? _a : contexts[contextIndex] = {
            itemId: yKey,
            nodeData: [],
            labelData: [],
            scales: __superGet(_BarSeries2.prototype, this, "calculateScaling").call(this),
            visible: this.visible || animationEnabled
          };
          const xValue = keys[xIndex];
          const x = xScale.convert(xValue);
          const currY = +value[yEndIndex];
          const prevY = +value[yStartIndex];
          const yRawValue = value[yRawIndex];
          const isPositive = yRawValue >= 0;
          const isUpward = isPositive !== yReversed;
          const yRange = (_b = aggValues == null ? void 0 : aggValues[yRangeIndex][isPositive ? 1 : 0]) != null ? _b : 0;
          const barX = x + groupScale.convert(String(groupIndex));
          if (isNaN(currY)) {
            return;
          }
          const y = yScale.convert(currY);
          const bottomY = yScale.convert(prevY);
          const barAlongX = this.getBarDirection() === "x";
          const bboxHeight = yScale.convert(yRange);
          const bboxBottom = yScale.convert(0);
          const cornerRadiusBbox = new BBox(
            barAlongX ? Math.min(bboxBottom, bboxHeight) : barX,
            barAlongX ? barX : Math.min(bboxBottom, bboxHeight),
            barAlongX ? Math.abs(bboxBottom - bboxHeight) : barWidth,
            barAlongX ? barWidth : Math.abs(bboxBottom - bboxHeight)
          );
          const rect = {
            x: barAlongX ? Math.min(y, bottomY) : barX,
            y: barAlongX ? barX : Math.min(y, bottomY),
            width: barAlongX ? Math.abs(bottomY - y) : barWidth,
            height: barAlongX ? barWidth : Math.abs(bottomY - y),
            cornerRadiusBbox
          };
          const {
            fontStyle: labelFontStyle,
            fontWeight: labelFontWeight,
            fontSize: labelFontSize,
            fontFamily: labelFontFamily,
            color: labelColor,
            placement
          } = label;
          const labelText = this.getLabelText(
            this.properties.label,
            {
              datum: seriesDatum[contextIndex],
              value: yRawValue,
              xKey,
              yKey,
              xName,
              yName,
              legendItemName
            },
            (value2) => isNumber2(value2) ? value2.toFixed(2) : ""
          );
          const labelDatum = labelText ? __spreadValues({
            text: labelText,
            fill: labelColor,
            fontStyle: labelFontStyle,
            fontWeight: labelFontWeight,
            fontSize: labelFontSize,
            fontFamily: labelFontFamily
          }, adjustLabelPlacement({
            isPositive,
            isVertical: !barAlongX,
            placement,
            rect
          })) : void 0;
          const lengthRatioMultiplier = this.shouldFlipXY() ? rect.height : rect.width;
          const nodeData = {
            series: this,
            itemId: yKey,
            datum: seriesDatum[contextIndex],
            cumulativeValue: currY,
            xValue,
            yValue: yRawValue,
            yKey,
            xKey,
            capDefaults: {
              lengthRatioMultiplier,
              lengthMax: lengthRatioMultiplier
            },
            x: rect.x,
            y: rect.y,
            width: rect.width,
            height: rect.height,
            midPoint: { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 },
            fill,
            stroke,
            strokeWidth,
            cornerRadius,
            topLeftCornerRadius: !(barAlongX === isUpward),
            topRightCornerRadius: isUpward,
            bottomRightCornerRadius: barAlongX === isUpward,
            bottomLeftCornerRadius: !isUpward,
            cornerRadiusBbox,
            label: labelDatum
          };
          contexts[contextIndex].nodeData.push(nodeData);
          contexts[contextIndex].labelData.push(nodeData);
        });
      });
      return contexts;
    });
  }
  nodeFactory() {
    return new Rect();
  }
  updateDatumSelection(opts) {
    return __async(this, null, function* () {
      return opts.datumSelection.update(
        opts.nodeData,
        (rect) => {
          rect.tag = 0;
        },
        (datum) => datum.xValue
      );
    });
  }
  updateDatumNodes(opts) {
    return __async(this, null, function* () {
      if (!this.properties.isValid()) {
        return;
      }
      const {
        yKey,
        stackGroup,
        fill,
        fillOpacity,
        stroke,
        strokeWidth,
        strokeOpacity,
        lineDash,
        lineDashOffset,
        formatter,
        shadow,
        highlightStyle: { item: itemHighlightStyle }
      } = this.properties;
      const xAxis = this.axes[
        "x"
        /* X */
      ];
      const crisp = checkCrisp(xAxis == null ? void 0 : xAxis.visibleRange);
      const categoryAlongX = this.getCategoryDirection() === "x";
      opts.datumSelection.each((rect, datum) => {
        const style = {
          fill,
          stroke,
          fillOpacity,
          strokeOpacity,
          lineDash,
          lineDashOffset,
          fillShadow: shadow,
          strokeWidth: this.getStrokeWidth(strokeWidth),
          cornerRadius: datum.cornerRadius,
          topLeftCornerRadius: datum.topLeftCornerRadius,
          topRightCornerRadius: datum.topRightCornerRadius,
          bottomRightCornerRadius: datum.bottomRightCornerRadius,
          bottomLeftCornerRadius: datum.bottomLeftCornerRadius,
          cornerRadiusBbox: datum.cornerRadiusBbox
        };
        const visible = categoryAlongX ? datum.width > 0 : datum.height > 0;
        const config = getRectConfig({
          datum,
          ctx: this.ctx,
          seriesId: this.id,
          isHighlighted: opts.isHighlight,
          highlightStyle: itemHighlightStyle,
          yKey,
          style,
          formatter,
          stackGroup
        });
        config.crisp = crisp;
        config.visible = visible;
        updateRect({ rect, config });
      });
    });
  }
  updateLabelSelection(opts) {
    return __async(this, null, function* () {
      const data = this.isLabelEnabled() ? opts.labelData : [];
      return opts.labelSelection.update(data, (text) => {
        text.tag = 1;
        text.pointerEvents = 1;
      });
    });
  }
  updateLabelNodes(opts) {
    return __async(this, null, function* () {
      opts.labelSelection.each((textNode, datum) => {
        updateLabelNode(textNode, this.properties.label, datum.label);
      });
    });
  }
  getTooltipHtml(nodeDatum) {
    var _a;
    const {
      id: seriesId,
      processedData,
      ctx: { callbackCache }
    } = this;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!processedData || !this.properties.isValid() || !xAxis || !yAxis) {
      return "";
    }
    const { xKey, yKey, xName, yName, fill, stroke, strokeWidth, tooltip, formatter, stackGroup } = this.properties;
    const { xValue, yValue, datum } = nodeDatum;
    const xString = xAxis.formatDatum(xValue);
    const yString = yAxis.formatDatum(yValue);
    const title = sanitizeHtml(yName);
    const content = sanitizeHtml(xString + ": " + yString);
    let format2;
    if (formatter) {
      format2 = callbackCache.call(formatter, {
        seriesId,
        datum,
        xKey,
        yKey,
        stackGroup,
        fill,
        stroke,
        strokeWidth: this.getStrokeWidth(strokeWidth),
        highlighted: false
      });
    }
    const color = (_a = format2 == null ? void 0 : format2.fill) != null ? _a : fill;
    return tooltip.toTooltipHtml(
      { title, content, backgroundColor: color },
      __spreadValues({
        seriesId,
        datum,
        xKey,
        yKey,
        xName,
        yName,
        stackGroup,
        title,
        color
      }, this.getModuleTooltipParams())
    );
  }
  getLegendData(legendType) {
    var _a, _b;
    const { showInLegend } = this.properties;
    if (legendType !== "category" || !((_a = this.data) == null ? void 0 : _a.length) || !this.properties.isValid() || !showInLegend) {
      return [];
    }
    const { yKey, yName, fill, stroke, strokeWidth, fillOpacity, strokeOpacity, legendItemName, visible } = this.properties;
    return [
      {
        legendType: "category",
        id: this.id,
        itemId: yKey,
        seriesId: this.id,
        enabled: visible,
        label: { text: (_b = legendItemName != null ? legendItemName : yName) != null ? _b : yKey },
        marker: { fill, fillOpacity, stroke, strokeWidth, strokeOpacity },
        legendItemName
      }
    ];
  }
  animateEmptyUpdateReady({ datumSelections, labelSelections, annotationSelections }) {
    const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(this.isVertical(), this.axes));
    fromToMotion(this.id, "nodes", this.ctx.animationManager, datumSelections, fns);
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelections);
    seriesLabelFadeInAnimation(this, "annotations", this.ctx.animationManager, annotationSelections);
  }
  animateWaitingUpdateReady(data) {
    var _a, _b;
    const { datumSelections, labelSelections, annotationSelections } = data;
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    const diff2 = (_b = (_a = this.processedData) == null ? void 0 : _a.reduced) == null ? void 0 : _b.diff;
    const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(this.isVertical(), this.axes));
    fromToMotion(
      this.id,
      "nodes",
      this.ctx.animationManager,
      datumSelections,
      fns,
      (_, datum) => String(datum.xValue),
      diff2
    );
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelections);
    seriesLabelFadeInAnimation(this, "annotations", this.ctx.animationManager, annotationSelections);
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
};
_BarSeries.className = "BarSeries";
_BarSeries.type = "bar";
var BarSeries = _BarSeries;
var BarSeriesModule = {
  type: "series",
  optionsKey: "series[]",
  packageType: "community",
  chartTypes: ["cartesian"],
  identifier: "bar",
  instanceConstructor: BarSeries,
  stackable: true,
  groupable: true,
  seriesDefaults: {
    axes: [
      {
        type: CARTESIAN_AXIS_TYPES.NUMBER,
        position: CARTESIAN_AXIS_POSITIONS.LEFT
      },
      {
        type: CARTESIAN_AXIS_TYPES.CATEGORY,
        position: CARTESIAN_AXIS_POSITIONS.BOTTOM
      }
    ]
  },
  swapDefaultAxesCondition: (series) => (series == null ? void 0 : series.direction) === "horizontal",
  themeTemplate: {
    __extends__: EXTENDS_SERIES_DEFAULTS,
    fillOpacity: 1,
    strokeWidth: 0,
    lineDash: [0],
    lineDashOffset: 0,
    label: {
      enabled: false,
      fontStyle: void 0,
      fontWeight: FONT_WEIGHT2.NORMAL,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_INSIDE_SERIES_LABEL_COLOUR,
      formatter: void 0,
      placement: "inside"
    },
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    }
  },
  enterpriseThemeTemplate: {
    errorBar: {
      cap: {
        lengthRatio: 0.3
      }
    }
  },
  paletteFactory: singleSeriesPaletteFactory
};
var BubbleSeriesMarker = class extends SeriesMarker {
  constructor() {
    super(...arguments);
    this.maxSize = 30;
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], BubbleSeriesMarker.prototype, "maxSize", 2);
__decorateClass([
  Validate(NUMBER_ARRAY, { optional: true }),
  SceneChangeDetection({
    redraw: 3
    /* MAJOR */
  })
], BubbleSeriesMarker.prototype, "domain", 2);
var BubbleSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.colorRange = ["#ffff00", "#00ff00", "#0000ff"];
    this.marker = new BubbleSeriesMarker();
    this.label = new Label();
    this.tooltip = new SeriesTooltip();
  }
};
__decorateClass([
  Validate(STRING)
], BubbleSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  Validate(STRING)
], BubbleSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  Validate(STRING)
], BubbleSeriesProperties.prototype, "sizeKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BubbleSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BubbleSeriesProperties.prototype, "colorKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BubbleSeriesProperties.prototype, "xName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BubbleSeriesProperties.prototype, "yName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BubbleSeriesProperties.prototype, "sizeName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BubbleSeriesProperties.prototype, "labelName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BubbleSeriesProperties.prototype, "colorName", 2);
__decorateClass([
  Validate(NUMBER_ARRAY, { optional: true })
], BubbleSeriesProperties.prototype, "colorDomain", 2);
__decorateClass([
  Validate(COLOR_STRING_ARRAY)
], BubbleSeriesProperties.prototype, "colorRange", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], BubbleSeriesProperties.prototype, "title", 2);
__decorateClass([
  Validate(OBJECT)
], BubbleSeriesProperties.prototype, "marker", 2);
__decorateClass([
  Validate(OBJECT)
], BubbleSeriesProperties.prototype, "label", 2);
__decorateClass([
  Validate(OBJECT)
], BubbleSeriesProperties.prototype, "tooltip", 2);
var BubbleSeriesNodeClickEvent = class extends CartesianSeriesNodeClickEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.sizeKey = series.properties.sizeKey;
  }
};
var _BubbleSeries = class _BubbleSeries2 extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [
        2,
        3,
        0
        /* EXACT_SHAPE_MATCH */
      ],
      pathsPerSeries: 0,
      hasMarkers: true,
      markerSelectionGarbageCollection: false,
      animationResetFns: {
        label: resetLabelFn,
        marker: resetMarkerFn
      }
    });
    this.NodeClickEvent = BubbleSeriesNodeClickEvent;
    this.properties = new BubbleSeriesProperties();
    this.sizeScale = new LinearScale();
    this.colorScale = new ColorScale();
  }
  processData(dataController) {
    return __async(this, null, function* () {
      var _a, _b;
      if (!this.properties.isValid() || this.data == null) {
        return;
      }
      const { isContinuousX, isContinuousY } = this.isContinuous();
      const { xKey, yKey, sizeKey, labelKey, colorDomain, colorRange, colorKey, marker } = this.properties;
      const { dataModel, processedData } = yield this.requestDataModel(dataController, this.data, {
        props: [
          keyProperty(this, xKey, isContinuousX, { id: "xKey-raw" }),
          keyProperty(this, yKey, isContinuousY, { id: "yKey-raw" }),
          ...labelKey ? [keyProperty(this, labelKey, false, { id: `labelKey-raw` })] : [],
          valueProperty(this, xKey, isContinuousX, { id: `xValue` }),
          valueProperty(this, yKey, isContinuousY, { id: `yValue` }),
          valueProperty(this, sizeKey, true, { id: `sizeValue` }),
          ...colorKey ? [valueProperty(this, colorKey, true, { id: `colorValue` })] : [],
          ...labelKey ? [valueProperty(this, labelKey, false, { id: `labelValue` })] : []
        ],
        dataVisible: this.visible
      });
      const sizeKeyIdx = dataModel.resolveProcessedDataIndexById(this, `sizeValue`).index;
      const processedSize = (_a = processedData.domain.values[sizeKeyIdx]) != null ? _a : [];
      this.sizeScale.domain = marker.domain ? marker.domain : processedSize;
      if (colorKey) {
        const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, `colorValue`).index;
        this.colorScale.domain = (_b = colorDomain != null ? colorDomain : processedData.domain.values[colorKeyIdx]) != null ? _b : [];
        this.colorScale.range = colorRange;
        this.colorScale.update();
      }
      this.animationState.transition("updateData");
    });
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData } = this;
    if (!processedData || !dataModel)
      return [];
    const id = direction === "x" ? `xValue` : `yValue`;
    const dataDef = dataModel.resolveProcessedDataDefById(this, id);
    const domain = dataModel.getDomain(this, id, "value", processedData);
    if ((dataDef == null ? void 0 : dataDef.def.type) === "value" && (dataDef == null ? void 0 : dataDef.def.valueType) === "category") {
      return domain;
    }
    const axis = this.axes[direction];
    return fixNumericExtent(extent(domain), axis);
  }
  createNodeData() {
    return __async(this, null, function* () {
      var _a, _b, _c;
      const { axes, dataModel, processedData, colorScale, sizeScale } = this;
      const { xKey, yKey, sizeKey, labelKey, xName, yName, sizeName, labelName, label, colorKey, marker, visible } = this.properties;
      const xAxis = axes[
        "x"
        /* X */
      ];
      const yAxis = axes[
        "y"
        /* Y */
      ];
      if (!(dataModel && processedData && visible && xAxis && yAxis)) {
        return [];
      }
      const xDataIdx = dataModel.resolveProcessedDataIndexById(this, `xValue`).index;
      const yDataIdx = dataModel.resolveProcessedDataIndexById(this, `yValue`).index;
      const sizeDataIdx = sizeKey ? dataModel.resolveProcessedDataIndexById(this, `sizeValue`).index : -1;
      const colorDataIdx = colorKey ? dataModel.resolveProcessedDataIndexById(this, `colorValue`).index : -1;
      const labelDataIdx = labelKey ? dataModel.resolveProcessedDataIndexById(this, `labelValue`).index : -1;
      const xScale = xAxis.scale;
      const yScale = yAxis.scale;
      const xOffset = ((_a = xScale.bandwidth) != null ? _a : 0) / 2;
      const yOffset = ((_b = yScale.bandwidth) != null ? _b : 0) / 2;
      const nodeData = [];
      sizeScale.range = [marker.size, marker.maxSize];
      const font = label.getFont();
      for (const { values, datum } of (_c = processedData.data) != null ? _c : []) {
        const xDatum = values[xDataIdx];
        const yDatum = values[yDataIdx];
        const x = xScale.convert(xDatum) + xOffset;
        const y = yScale.convert(yDatum) + yOffset;
        const labelText = this.getLabelText(label, {
          value: labelKey ? values[labelDataIdx] : yDatum,
          datum,
          xKey,
          yKey,
          sizeKey,
          labelKey,
          xName,
          yName,
          sizeName,
          labelName
        });
        const size = HdpiCanvas.getTextSize(String(labelText), font);
        const markerSize = sizeKey ? sizeScale.convert(values[sizeDataIdx]) : marker.size;
        const fill = colorKey ? colorScale.convert(values[colorDataIdx]) : void 0;
        nodeData.push({
          series: this,
          itemId: yKey,
          yKey,
          xKey,
          datum,
          xValue: xDatum,
          yValue: yDatum,
          sizeValue: values[sizeDataIdx],
          point: { x, y, size: markerSize },
          midPoint: { x, y },
          fill,
          label: __spreadValues({ text: labelText }, size)
        });
      }
      return [
        {
          itemId: yKey,
          nodeData,
          labelData: nodeData,
          scales: __superGet(_BubbleSeries2.prototype, this, "calculateScaling").call(this),
          visible: this.visible
        }
      ];
    });
  }
  isPathOrSelectionDirty() {
    return this.properties.marker.isDirty();
  }
  getLabelData() {
    var _a;
    return (_a = this.contextNodeData) == null ? void 0 : _a.reduce((r, n) => r.concat(n.labelData), []);
  }
  markerFactory() {
    const { shape } = this.properties.marker;
    const MarkerShape = getMarker(shape);
    return new MarkerShape();
  }
  updateMarkerSelection(opts) {
    return __async(this, null, function* () {
      const { nodeData, markerSelection } = opts;
      if (this.properties.marker.isDirty()) {
        markerSelection.clear();
        markerSelection.cleanup();
      }
      const data = this.properties.marker.enabled ? nodeData : [];
      return markerSelection.update(data, void 0, (datum) => this.getDatumId(datum));
    });
  }
  updateMarkerNodes(opts) {
    return __async(this, null, function* () {
      const { markerSelection, isHighlight: highlighted } = opts;
      const { xKey, yKey, sizeKey, labelKey, marker } = this.properties;
      const baseStyle = mergeDefaults(highlighted && this.properties.highlightStyle.item, marker.getStyle());
      this.sizeScale.range = [marker.size, marker.maxSize];
      markerSelection.each((node, datum) => {
        this.updateMarkerStyle(node, marker, { datum, highlighted, xKey, yKey, sizeKey, labelKey }, baseStyle);
      });
      if (!highlighted) {
        this.properties.marker.markClean();
      }
    });
  }
  updateLabelSelection(opts) {
    return __async(this, null, function* () {
      var _a, _b;
      const placedLabels = this.properties.label.enabled ? (_b = (_a = this.chart) == null ? void 0 : _a.placeLabels().get(this)) != null ? _b : [] : [];
      return opts.labelSelection.update(
        placedLabels.map((v) => __spreadProps(__spreadValues({}, v.datum), {
          point: {
            x: v.x,
            y: v.y,
            size: v.datum.point.size
          }
        }))
      );
    });
  }
  updateLabelNodes(opts) {
    return __async(this, null, function* () {
      const { label } = this.properties;
      opts.labelSelection.each((text, datum) => {
        var _a, _b, _c, _d;
        text.text = datum.label.text;
        text.fill = label.color;
        text.x = (_b = (_a = datum.point) == null ? void 0 : _a.x) != null ? _b : 0;
        text.y = (_d = (_c = datum.point) == null ? void 0 : _c.y) != null ? _d : 0;
        text.fontStyle = label.fontStyle;
        text.fontWeight = label.fontWeight;
        text.fontSize = label.fontSize;
        text.fontFamily = label.fontFamily;
        text.textAlign = "left";
        text.textBaseline = "top";
      });
    });
  }
  getTooltipHtml(nodeDatum) {
    var _a;
    const xAxis = this.axes[
      "x"
      /* X */
    ];
    const yAxis = this.axes[
      "y"
      /* Y */
    ];
    if (!this.properties.isValid() || !xAxis || !yAxis) {
      return "";
    }
    const { xKey, yKey, sizeKey, labelKey, xName, yName, sizeName, labelName, marker, tooltip } = this.properties;
    const title = (_a = this.properties.title) != null ? _a : yName;
    const baseStyle = mergeDefaults(
      { fill: nodeDatum.fill, strokeWidth: this.getStrokeWidth(marker.strokeWidth) },
      marker.getStyle()
    );
    const { fill: color = "gray" } = this.getMarkerStyle(
      marker,
      { datum: nodeDatum, highlighted: false, xKey, yKey, sizeKey, labelKey },
      baseStyle
    );
    const {
      datum,
      xValue,
      yValue,
      sizeValue,
      label: { text: labelText }
    } = nodeDatum;
    const xString = sanitizeHtml(xAxis.formatDatum(xValue));
    const yString = sanitizeHtml(yAxis.formatDatum(yValue));
    let content = `<b>${sanitizeHtml(xName != null ? xName : xKey)}</b>: ${xString}<br><b>${sanitizeHtml(yName != null ? yName : yKey)}</b>: ${yString}`;
    if (sizeKey) {
      content += `<br><b>${sanitizeHtml(sizeName != null ? sizeName : sizeKey)}</b>: ${sanitizeHtml(String(sizeValue))}`;
    }
    if (labelKey) {
      content = `<b>${sanitizeHtml(labelName != null ? labelName : labelKey)}</b>: ${sanitizeHtml(labelText)}<br>` + content;
    }
    return tooltip.toTooltipHtml(
      { title, content, backgroundColor: color },
      {
        datum,
        xKey,
        xName,
        yKey,
        yName,
        sizeKey,
        sizeName,
        labelKey,
        labelName,
        title,
        color,
        seriesId: this.id
      }
    );
  }
  getLegendData() {
    var _a, _b;
    if (!((_a = this.data) == null ? void 0 : _a.length) || !this.properties.isValid()) {
      return [];
    }
    const { yKey, yName, title, marker, visible } = this.properties;
    const { shape, fill, stroke, fillOpacity, strokeOpacity, strokeWidth } = marker;
    return [
      {
        legendType: "category",
        id: this.id,
        itemId: yKey,
        seriesId: this.id,
        enabled: visible,
        label: {
          text: (_b = title != null ? title : yName) != null ? _b : yKey
        },
        marker: {
          shape,
          fill: fill != null ? fill : "rgba(0, 0, 0, 0)",
          stroke: stroke != null ? stroke : "rgba(0, 0, 0, 0)",
          fillOpacity: fillOpacity != null ? fillOpacity : 1,
          strokeOpacity: strokeOpacity != null ? strokeOpacity : 1,
          strokeWidth: strokeWidth != null ? strokeWidth : 0
        }
      }
    ];
  }
  animateEmptyUpdateReady({ markerSelections, labelSelections }) {
    markerScaleInAnimation(this, this.ctx.animationManager, markerSelections);
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelections);
  }
  getDatumId(datum) {
    return createDatumId([`${datum.xValue}`, `${datum.yValue}`, datum.label.text]);
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  nodeFactory() {
    return new Group();
  }
};
_BubbleSeries.className = "BubbleSeries";
_BubbleSeries.type = "bubble";
var BubbleSeries = _BubbleSeries;
var BubbleSeriesModule = {
  type: "series",
  optionsKey: "series[]",
  packageType: "community",
  chartTypes: ["cartesian"],
  identifier: "bubble",
  instanceConstructor: BubbleSeries,
  seriesDefaults: {
    axes: [
      { type: CARTESIAN_AXIS_TYPES.NUMBER, position: CARTESIAN_AXIS_POSITIONS.BOTTOM },
      { type: CARTESIAN_AXIS_TYPES.NUMBER, position: CARTESIAN_AXIS_POSITIONS.LEFT }
    ]
  },
  themeTemplate: {
    __extends__: EXTENDS_SERIES_DEFAULTS,
    tooltip: {
      position: {
        type: "node"
      }
    },
    marker: {
      __extends__: EXTENDS_CARTESIAN_MARKER_DEFAULTS,
      maxSize: 30,
      fillOpacity: 0.8
    },
    label: {
      enabled: false,
      fontStyle: void 0,
      fontWeight: void 0,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_LABEL_COLOUR
    }
  },
  paletteFactory: markerPaletteFactory
};
var HistogramSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.fillOpacity = 1;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.areaPlot = false;
    this.aggregation = "sum";
    this.shadow = new DropShadow();
    this.label = new Label();
    this.tooltip = new SeriesTooltip();
  }
};
__decorateClass([
  Validate(STRING)
], HistogramSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], HistogramSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], HistogramSeriesProperties.prototype, "xName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], HistogramSeriesProperties.prototype, "yName", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], HistogramSeriesProperties.prototype, "fill", 2);
__decorateClass([
  Validate(RATIO)
], HistogramSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  Validate(COLOR_STRING, { optional: true })
], HistogramSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], HistogramSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO)
], HistogramSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  Validate(LINE_DASH)
], HistogramSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], HistogramSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  Validate(BOOLEAN)
], HistogramSeriesProperties.prototype, "areaPlot", 2);
__decorateClass([
  Validate(ARRAY, { optional: true })
], HistogramSeriesProperties.prototype, "bins", 2);
__decorateClass([
  Validate(UNION(["count", "sum", "mean"], "a histogram aggregation"))
], HistogramSeriesProperties.prototype, "aggregation", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], HistogramSeriesProperties.prototype, "binCount", 2);
__decorateClass([
  Validate(OBJECT)
], HistogramSeriesProperties.prototype, "shadow", 2);
__decorateClass([
  Validate(OBJECT)
], HistogramSeriesProperties.prototype, "label", 2);
__decorateClass([
  Validate(OBJECT)
], HistogramSeriesProperties.prototype, "tooltip", 2);
var defaultBinCount = 10;
var _HistogramSeries = class _HistogramSeries2 extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [
        0
        /* EXACT_SHAPE_MATCH */
      ],
      datumSelectionGarbageCollection: false,
      animationResetFns: {
        datum: resetBarSelectionsFn,
        label: resetLabelFn
      }
    });
    this.properties = new HistogramSeriesProperties();
    this.calculatedBins = [];
  }
  // During processData phase, used to unify different ways of the user specifying
  // the bins. Returns bins in format[[min1, max1], [min2, max2], ... ].
  deriveBins(xDomain) {
    if (this.properties.binCount) {
      return this.calculateNiceBins(xDomain, this.properties.binCount);
    }
    const binStarts = ticks_default(xDomain[0], xDomain[1], defaultBinCount);
    const binSize = tickStep(xDomain[0], xDomain[1], defaultBinCount);
    const [firstBinEnd] = binStarts;
    const expandStartToBin = (n) => [n, n + binSize];
    return [[firstBinEnd - binSize, firstBinEnd], ...binStarts.map(expandStartToBin)];
  }
  calculateNiceBins(domain, binCount) {
    const startGuess = Math.floor(domain[0]);
    const stop = domain[1];
    const segments = binCount || 1;
    const { start, binSize } = this.calculateNiceStart(startGuess, stop, segments);
    return this.getBins(start, stop, binSize, segments);
  }
  getBins(start, stop, step, count2) {
    const bins = [];
    const precision = this.calculatePrecision(step);
    for (let i = 0; i < count2; i++) {
      const a = Math.round((start + i * step) * precision) / precision;
      let b = Math.round((start + (i + 1) * step) * precision) / precision;
      if (i === count2 - 1) {
        b = Math.max(b, stop);
      }
      bins[i] = [a, b];
    }
    return bins;
  }
  calculatePrecision(step) {
    let precision = 10;
    if (isReal(step) && step > 0) {
      while (step < 1) {
        precision *= 10;
        step *= 10;
      }
    }
    return precision;
  }
  calculateNiceStart(a, b, segments) {
    const binSize = Math.abs(b - a) / segments;
    const order = Math.floor(Math.log10(binSize));
    const magnitude = Math.pow(10, order);
    const start = Math.floor(a / magnitude) * magnitude;
    return {
      start,
      binSize
    };
  }
  processData(dataController) {
    return __async(this, null, function* () {
      var _a;
      const { xKey, yKey, areaPlot, aggregation } = this.properties;
      const props = [keyProperty(this, xKey, true), SORT_DOMAIN_GROUPS];
      if (yKey) {
        let aggProp = groupCount(this, "groupCount");
        if (aggregation === "count") {
        } else if (aggregation === "sum") {
          aggProp = groupSum(this, "groupAgg");
        } else if (aggregation === "mean") {
          aggProp = groupAverage(this, "groupAgg");
        }
        if (areaPlot) {
          aggProp = area(this, "groupAgg", aggProp);
        }
        props.push(valueProperty(this, yKey, true, { invalidValue: void 0 }), aggProp);
      } else {
        let aggProp = groupCount(this, "groupAgg");
        if (areaPlot) {
          aggProp = area(this, "groupAgg", aggProp);
        }
        props.push(aggProp);
      }
      const groupByFn = (dataSet) => {
        var _a2;
        const xExtent = fixNumericExtent(dataSet.domain.keys[0]);
        if (xExtent.length === 0) {
          dataSet.domain.groups = [];
          return () => [];
        }
        const bins = (_a2 = this.properties.bins) != null ? _a2 : this.deriveBins(xExtent);
        const binCount = bins.length;
        this.calculatedBins = [...bins];
        return (item) => {
          const xValue = item.keys[0];
          for (let i = 0; i < binCount; i++) {
            const nextBin = bins[i];
            if (xValue >= nextBin[0] && xValue < nextBin[1]) {
              return nextBin;
            }
            if (i === binCount - 1 && xValue <= nextBin[1]) {
              return nextBin;
            }
          }
          return [];
        };
      };
      if (!this.ctx.animationManager.isSkipped() && this.processedData) {
        props.push(diff(this.processedData, false));
      }
      yield this.requestDataModel(dataController, (_a = this.data) != null ? _a : [], {
        props,
        dataVisible: this.visible,
        groupByFn
      });
      this.animationState.transition("updateData");
    });
  }
  getSeriesDomain(direction) {
    var _a, _b, _c, _d;
    const { processedData, dataModel } = this;
    if (!processedData || !dataModel || !this.calculatedBins.length)
      return [];
    const yDomain = dataModel.getDomain(this, `groupAgg`, "aggregate", processedData);
    const xDomainMin = (_a = this.calculatedBins) == null ? void 0 : _a[0][0];
    const xDomainMax = (_d = this.calculatedBins) == null ? void 0 : _d[((_c = (_b = this.calculatedBins) == null ? void 0 : _b.length) != null ? _c : 0) - 1][1];
    if (direction === "x") {
      return fixNumericExtent([xDomainMin, xDomainMax]);
    }
    return fixNumericExtent(yDomain);
  }
  createNodeData() {
    return __async(this, null, function* () {
      var _a;
      const {
        id: seriesId,
        axes,
        processedData,
        ctx: { callbackCache }
      } = this;
      const xAxis = axes[
        "x"
        /* X */
      ];
      const yAxis = axes[
        "y"
        /* Y */
      ];
      if (!this.visible || !xAxis || !yAxis || !processedData || processedData.type !== "grouped") {
        return [];
      }
      const { scale: xScale } = xAxis;
      const { scale: yScale } = yAxis;
      const { xKey, yKey, xName, yName, fill, stroke, strokeWidth } = this.properties;
      const {
        formatter: labelFormatter = (params) => String(params.value),
        fontStyle: labelFontStyle,
        fontWeight: labelFontWeight,
        fontSize: labelFontSize,
        fontFamily: labelFontFamily,
        color: labelColor
      } = this.properties.label;
      const nodeData = [];
      processedData.data.forEach((group2) => {
        var _a2;
        const {
          aggValues: [[negativeAgg, positiveAgg]] = [[0, 0]],
          datum,
          datum: { length: frequency },
          keys: domain,
          keys: [xDomainMin, xDomainMax]
        } = group2;
        const xMinPx = xScale.convert(xDomainMin);
        const xMaxPx = xScale.convert(xDomainMax);
        const total = negativeAgg + positiveAgg;
        const yZeroPx = yScale.convert(0);
        const yMaxPx = yScale.convert(total);
        const w = Math.abs(xMaxPx - xMinPx);
        const h = Math.abs(yMaxPx - yZeroPx);
        const x = Math.min(xMinPx, xMaxPx);
        const y = Math.min(yZeroPx, yMaxPx);
        const selectionDatumLabel = total !== 0 ? {
          text: (_a2 = callbackCache.call(labelFormatter, {
            value: total,
            datum,
            seriesId,
            xKey,
            yKey,
            xName,
            yName
          })) != null ? _a2 : String(total),
          fontStyle: labelFontStyle,
          fontWeight: labelFontWeight,
          fontSize: labelFontSize,
          fontFamily: labelFontFamily,
          fill: labelColor,
          x: x + w / 2,
          y: y + h / 2
        } : void 0;
        const nodeMidPoint = {
          x: x + w / 2,
          y: y + h / 2
        };
        nodeData.push({
          series: this,
          datum,
          // required by SeriesNodeDatum, but might not make sense here
          // since each selection is an aggregation of multiple data.
          aggregatedValue: total,
          frequency,
          domain,
          yKey,
          xKey,
          x,
          y,
          xValue: xMinPx,
          yValue: yMaxPx,
          width: w,
          height: h,
          midPoint: nodeMidPoint,
          fill,
          stroke,
          strokeWidth,
          label: selectionDatumLabel
        });
      });
      return [
        {
          itemId: (_a = this.properties.yKey) != null ? _a : this.id,
          nodeData,
          labelData: nodeData,
          scales: __superGet(_HistogramSeries2.prototype, this, "calculateScaling").call(this),
          animationValid: true,
          visible: this.visible
        }
      ];
    });
  }
  nodeFactory() {
    return new Rect();
  }
  updateDatumSelection(opts) {
    return __async(this, null, function* () {
      const { nodeData, datumSelection } = opts;
      return datumSelection.update(
        nodeData,
        (rect) => {
          rect.tag = 0;
          rect.crisp = true;
        },
        (datum) => datum.domain.join("_")
      );
    });
  }
  updateDatumNodes(opts) {
    return __async(this, null, function* () {
      const { isHighlight: isDatumHighlighted } = opts;
      const {
        fillOpacity: seriesFillOpacity,
        strokeOpacity,
        lineDash,
        lineDashOffset,
        shadow,
        highlightStyle: {
          item: {
            fill: highlightedFill,
            fillOpacity: highlightFillOpacity = seriesFillOpacity,
            stroke: highlightedStroke,
            strokeWidth: highlightedDatumStrokeWidth
          }
        }
      } = this.properties;
      opts.datumSelection.each((rect, datum, index) => {
        var _a, _b;
        const strokeWidth = isDatumHighlighted && highlightedDatumStrokeWidth !== void 0 ? highlightedDatumStrokeWidth : datum.strokeWidth;
        const fillOpacity = isDatumHighlighted ? highlightFillOpacity : seriesFillOpacity;
        rect.fill = (_a = isDatumHighlighted ? highlightedFill : void 0) != null ? _a : datum.fill;
        rect.stroke = (_b = isDatumHighlighted ? highlightedStroke : void 0) != null ? _b : datum.stroke;
        rect.fillOpacity = fillOpacity;
        rect.strokeOpacity = strokeOpacity;
        rect.strokeWidth = strokeWidth;
        rect.lineDash = lineDash;
        rect.lineDashOffset = lineDashOffset;
        rect.fillShadow = shadow;
        rect.zIndex = isDatumHighlighted ? Series.highlightedZIndex : index;
        rect.visible = datum.height > 0;
      });
    });
  }
  updateLabelSelection(opts) {
    return __async(this, null, function* () {
      const { labelData, labelSelection } = opts;
      return labelSelection.update(labelData, (text) => {
        text.tag = 1;
        text.pointerEvents = 1;
        text.textAlign = "center";
        text.textBaseline = "middle";
      });
    });
  }
  updateLabelNodes(opts) {
    return __async(this, null, function* () {
      const labelEnabled = this.isLabelEnabled();
      opts.labelSelection.each((text, datum) => {
        const label = datum.label;
        if (label && labelEnabled) {
          text.text = label.text;
          text.x = label.x;
          text.y = label.y;
          text.fontStyle = label.fontStyle;
          text.fontWeight = label.fontWeight;
          text.fontSize = label.fontSize;
          text.fontFamily = label.fontFamily;
          text.fill = label.fill;
          text.visible = true;
        } else {
          text.visible = false;
        }
      });
    });
  }
  getTooltipHtml(nodeDatum) {
    const xAxis = this.axes[
      "x"
      /* X */
    ];
    const yAxis = this.axes[
      "y"
      /* Y */
    ];
    if (!this.properties.isValid() || !xAxis || !yAxis) {
      return "";
    }
    const { xKey, yKey, xName, yName, fill: color, aggregation, tooltip } = this.properties;
    const {
      aggregatedValue,
      frequency,
      domain: [rangeMin, rangeMax]
    } = nodeDatum;
    const title = `${sanitizeHtml(xName != null ? xName : xKey)}: ${xAxis.formatDatum(rangeMin)} - ${xAxis.formatDatum(rangeMax)}`;
    let content = yKey ? `<b>${sanitizeHtml(yName != null ? yName : yKey)} (${aggregation})</b>: ${yAxis.formatDatum(aggregatedValue)}<br>` : "";
    content += `<b>Frequency</b>: ${frequency}`;
    const defaults = {
      title,
      backgroundColor: color,
      content
    };
    return tooltip.toTooltipHtml(defaults, {
      datum: {
        data: nodeDatum.datum,
        aggregatedValue: nodeDatum.aggregatedValue,
        domain: nodeDatum.domain,
        frequency: nodeDatum.frequency
      },
      xKey,
      xName,
      yKey,
      yName,
      color,
      title,
      seriesId: this.id
    });
  }
  getLegendData(legendType) {
    var _a, _b;
    if (!((_a = this.data) == null ? void 0 : _a.length) || legendType !== "category") {
      return [];
    }
    const { xKey, yName, fill, fillOpacity, stroke, strokeWidth, strokeOpacity, visible } = this.properties;
    return [
      {
        legendType: "category",
        id: this.id,
        itemId: xKey,
        seriesId: this.id,
        enabled: visible,
        label: {
          text: (_b = yName != null ? yName : xKey) != null ? _b : "Frequency"
        },
        marker: {
          fill: fill != null ? fill : "rgba(0, 0, 0, 0)",
          stroke: stroke != null ? stroke : "rgba(0, 0, 0, 0)",
          fillOpacity,
          strokeOpacity,
          strokeWidth
        }
      }
    ];
  }
  animateEmptyUpdateReady({ datumSelections, labelSelections }) {
    const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(true, this.axes));
    fromToMotion(this.id, "datums", this.ctx.animationManager, datumSelections, fns);
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelections);
  }
  animateWaitingUpdateReady(data) {
    var _a, _b;
    const diff2 = (_b = (_a = this.processedData) == null ? void 0 : _a.reduced) == null ? void 0 : _b.diff;
    const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(true, this.axes));
    fromToMotion(
      this.id,
      "datums",
      this.ctx.animationManager,
      data.datumSelections,
      fns,
      (_, datum) => this.getDatumId(datum),
      diff2
    );
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, data.labelSelections);
  }
  getDatumId(datum) {
    return createDatumId(datum.domain.map((d) => `${d}`));
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
};
_HistogramSeries.className = "HistogramSeries";
_HistogramSeries.type = "histogram";
var HistogramSeries = _HistogramSeries;
var HistogramSeriesModule = {
  type: "series",
  optionsKey: "series[]",
  packageType: "community",
  chartTypes: ["cartesian"],
  identifier: "histogram",
  instanceConstructor: HistogramSeries,
  seriesDefaults: {
    axes: [
      { type: CARTESIAN_AXIS_TYPES.NUMBER, position: CARTESIAN_AXIS_POSITIONS.BOTTOM },
      { type: CARTESIAN_AXIS_TYPES.NUMBER, position: CARTESIAN_AXIS_POSITIONS.LEFT }
    ]
  },
  themeTemplate: {
    __extends__: EXTENDS_SERIES_DEFAULTS,
    strokeWidth: 1,
    fillOpacity: 1,
    strokeOpacity: 1,
    lineDash: [0],
    lineDashOffset: 0,
    label: {
      enabled: false,
      fontStyle: void 0,
      fontWeight: void 0,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_INSIDE_SERIES_LABEL_COLOUR,
      formatter: void 0
    },
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    }
  },
  paletteFactory: ({ takeColors }) => {
    const {
      fills: [fill],
      strokes: [stroke]
    } = takeColors(1);
    return { fill, stroke };
  }
};
var LineSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.stroke = "#874349";
    this.strokeWidth = 2;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.marker = new SeriesMarker();
    this.label = new Label();
    this.tooltip = new SeriesTooltip();
    this.connectMissingData = false;
  }
};
__decorateClass([
  Validate(STRING)
], LineSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  Validate(STRING)
], LineSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], LineSeriesProperties.prototype, "xName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], LineSeriesProperties.prototype, "yName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], LineSeriesProperties.prototype, "title", 2);
__decorateClass([
  Validate(COLOR_STRING)
], LineSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], LineSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(RATIO)
], LineSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  Validate(LINE_DASH)
], LineSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], LineSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  Validate(OBJECT)
], LineSeriesProperties.prototype, "marker", 2);
__decorateClass([
  Validate(OBJECT)
], LineSeriesProperties.prototype, "label", 2);
__decorateClass([
  Validate(OBJECT)
], LineSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  Validate(BOOLEAN)
], LineSeriesProperties.prototype, "connectMissingData", 2);
var _LineSeries = class _LineSeries2 extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      hasMarkers: true,
      pickModes: [
        2,
        3,
        0
        /* EXACT_SHAPE_MATCH */
      ],
      markerSelectionGarbageCollection: false,
      animationResetFns: {
        path: buildResetPathFn({ getOpacity: () => this.getOpacity() }),
        label: resetLabelFn,
        marker: (node, datum) => __spreadValues(__spreadValues({}, resetMarkerFn(node)), resetMarkerPositionFn(node, datum))
      }
    });
    this.properties = new LineSeriesProperties();
  }
  processData(dataController) {
    return __async(this, null, function* () {
      if (!this.properties.isValid() || this.data == null) {
        return;
      }
      const { xKey, yKey } = this.properties;
      const animationEnabled = !this.ctx.animationManager.isSkipped();
      const { isContinuousX, isContinuousY } = this.isContinuous();
      const props = [];
      if (!isContinuousX) {
        props.push(keyProperty(this, xKey, isContinuousX, { id: "xKey" }));
        if (animationEnabled && this.processedData) {
          props.push(diff(this.processedData));
        }
      }
      if (animationEnabled) {
        props.push(animationValidation(this, isContinuousX ? ["xValue"] : []));
      }
      props.push(
        valueProperty(this, xKey, isContinuousX, { id: "xValue" }),
        valueProperty(this, yKey, isContinuousY, { id: "yValue", invalidValue: void 0 })
      );
      yield this.requestDataModel(dataController, this.data, { props });
      this.animationState.transition("updateData");
    });
  }
  getSeriesDomain(direction) {
    const { axes, dataModel, processedData } = this;
    if (!processedData || !dataModel)
      return [];
    const xAxis = axes[
      "x"
      /* X */
    ];
    const yAxis = axes[
      "y"
      /* Y */
    ];
    const xDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
    if (direction === "x") {
      const domain = dataModel.getDomain(this, `xValue`, "value", processedData);
      if ((xDef == null ? void 0 : xDef.def.type) === "value" && xDef.def.valueType === "category") {
        return domain;
      }
      return fixNumericExtent(extent(domain), xAxis);
    } else {
      const domain = dataModel.getDomain(this, `yValue`, "value", processedData);
      return fixNumericExtent(domain, yAxis);
    }
  }
  createNodeData() {
    return __async(this, null, function* () {
      var _a, _b, _c;
      const { processedData, dataModel, axes } = this;
      const xAxis = axes[
        "x"
        /* X */
      ];
      const yAxis = axes[
        "y"
        /* Y */
      ];
      if (!processedData || !dataModel || !xAxis || !yAxis) {
        return [];
      }
      const { xKey, yKey, xName, yName, marker, label, connectMissingData } = this.properties;
      const xScale = xAxis.scale;
      const yScale = yAxis.scale;
      const xOffset = ((_a = xScale.bandwidth) != null ? _a : 0) / 2;
      const yOffset = ((_b = yScale.bandwidth) != null ? _b : 0) / 2;
      const nodeData = [];
      const size = marker.enabled ? marker.size : 0;
      const xIdx = dataModel.resolveProcessedDataIndexById(this, `xValue`).index;
      const yIdx = dataModel.resolveProcessedDataIndexById(this, `yValue`).index;
      let moveTo = true;
      let nextPoint;
      for (let i = 0; i < processedData.data.length; i++) {
        const { datum, values } = nextPoint != null ? nextPoint : processedData.data[i];
        const xDatum = values[xIdx];
        const yDatum = values[yIdx];
        if (yDatum === void 0) {
          moveTo = !connectMissingData;
        } else {
          const x = xScale.convert(xDatum) + xOffset;
          if (isNaN(x)) {
            moveTo = !connectMissingData;
            nextPoint = void 0;
            continue;
          }
          nextPoint = ((_c = processedData.data[i + 1]) == null ? void 0 : _c.values[yIdx]) === void 0 ? void 0 : processedData.data[i + 1];
          const y = yScale.convert(yDatum) + yOffset;
          const labelText = this.getLabelText(
            label,
            { value: yDatum, datum, xKey, yKey, xName, yName },
            (value) => isNumber2(value) ? value.toFixed(2) : String(value)
          );
          nodeData.push({
            series: this,
            datum,
            yKey,
            xKey,
            point: { x, y, moveTo, size },
            midPoint: { x, y },
            yValue: yDatum,
            xValue: xDatum,
            capDefaults: { lengthRatioMultiplier: this.properties.marker.getDiameter(), lengthMax: Infinity },
            label: labelText ? {
              text: labelText,
              fontStyle: label.fontStyle,
              fontWeight: label.fontWeight,
              fontSize: label.fontSize,
              fontFamily: label.fontFamily,
              textAlign: "center",
              textBaseline: "bottom",
              fill: label.color
            } : void 0
          });
          moveTo = false;
        }
      }
      return [
        {
          itemId: yKey,
          nodeData,
          labelData: nodeData,
          scales: __superGet(_LineSeries2.prototype, this, "calculateScaling").call(this),
          visible: this.visible
        }
      ];
    });
  }
  isPathOrSelectionDirty() {
    return this.properties.marker.isDirty();
  }
  markerFactory() {
    const { shape } = this.properties.marker;
    const MarkerShape = getMarker(shape);
    return new MarkerShape();
  }
  updatePathNodes(opts) {
    return __async(this, null, function* () {
      const {
        paths: [lineNode],
        opacity,
        visible,
        animationEnabled
      } = opts;
      lineNode.setProperties({
        fill: void 0,
        lineJoin: "round",
        pointerEvents: 1,
        opacity,
        stroke: this.properties.stroke,
        strokeWidth: this.getStrokeWidth(this.properties.strokeWidth),
        strokeOpacity: this.properties.strokeOpacity,
        lineDash: this.properties.lineDash,
        lineDashOffset: this.properties.lineDashOffset
      });
      if (!animationEnabled) {
        lineNode.visible = visible;
      }
      updateClipPath(this, lineNode);
    });
  }
  updateMarkerSelection(opts) {
    return __async(this, null, function* () {
      let { nodeData } = opts;
      const { markerSelection } = opts;
      const { shape, enabled } = this.properties.marker;
      nodeData = shape && enabled ? nodeData : [];
      if (this.properties.marker.isDirty()) {
        markerSelection.clear();
        markerSelection.cleanup();
      }
      return markerSelection.update(nodeData, void 0, (datum) => this.getDatumId(datum));
    });
  }
  updateMarkerNodes(opts) {
    return __async(this, null, function* () {
      const { markerSelection, isHighlight: highlighted } = opts;
      const { xKey, yKey, stroke, strokeWidth, strokeOpacity, marker, highlightStyle } = this.properties;
      const baseStyle = mergeDefaults(highlighted && highlightStyle.item, marker.getStyle(), {
        stroke,
        strokeWidth,
        strokeOpacity
      });
      const applyTranslation = this.ctx.animationManager.isSkipped();
      markerSelection.each((node, datum) => {
        this.updateMarkerStyle(node, marker, { datum, highlighted, xKey, yKey }, baseStyle, { applyTranslation });
      });
      if (!highlighted) {
        marker.markClean();
      }
    });
  }
  updateLabelSelection(opts) {
    return __async(this, null, function* () {
      return opts.labelSelection.update(this.isLabelEnabled() ? opts.labelData : []);
    });
  }
  updateLabelNodes(opts) {
    return __async(this, null, function* () {
      const { enabled, fontStyle, fontWeight, fontSize, fontFamily, color } = this.properties.label;
      opts.labelSelection.each((text, datum) => {
        const { point, label } = datum;
        if (datum && label && enabled) {
          text.fontStyle = fontStyle;
          text.fontWeight = fontWeight;
          text.fontSize = fontSize;
          text.fontFamily = fontFamily;
          text.textAlign = label.textAlign;
          text.textBaseline = label.textBaseline;
          text.text = label.text;
          text.x = point.x;
          text.y = point.y - 10;
          text.fill = color;
          text.visible = true;
        } else {
          text.visible = false;
        }
      });
    });
  }
  getTooltipHtml(nodeDatum) {
    var _a;
    const xAxis = this.axes[
      "x"
      /* X */
    ];
    const yAxis = this.axes[
      "y"
      /* Y */
    ];
    if (!this.properties.isValid() || !xAxis || !yAxis) {
      return "";
    }
    const { xKey, yKey, xName, yName, strokeWidth, marker, tooltip } = this.properties;
    const { datum, xValue, yValue } = nodeDatum;
    const xString = xAxis.formatDatum(xValue);
    const yString = yAxis.formatDatum(yValue);
    const title = sanitizeHtml((_a = this.properties.title) != null ? _a : yName);
    const content = sanitizeHtml(xString + ": " + yString);
    const baseStyle = mergeDefaults({ fill: marker.stroke }, marker.getStyle(), { strokeWidth });
    const { fill: color } = this.getMarkerStyle(
      marker,
      { datum: nodeDatum, xKey, yKey, highlighted: false },
      baseStyle
    );
    return tooltip.toTooltipHtml(
      { title, content, backgroundColor: color },
      __spreadValues({
        datum,
        xKey,
        xName,
        yKey,
        yName,
        title,
        color,
        seriesId: this.id
      }, this.getModuleTooltipParams())
    );
  }
  getLegendData(legendType) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _i;
    if (!(((_a = this.data) == null ? void 0 : _a.length) && this.properties.isValid() && legendType === "category")) {
      return [];
    }
    const { yKey, yName, stroke, strokeOpacity, strokeWidth, lineDash, title, marker, visible } = this.properties;
    const color0 = "rgba(0, 0, 0, 0)";
    return [
      {
        legendType: "category",
        id: this.id,
        itemId: yKey,
        seriesId: this.id,
        enabled: visible,
        label: {
          text: (_b = title != null ? title : yName) != null ? _b : yKey
        },
        marker: {
          shape: marker.shape,
          fill: (_c = marker.fill) != null ? _c : color0,
          stroke: (_e = (_d = marker.stroke) != null ? _d : stroke) != null ? _e : color0,
          fillOpacity: (_f = marker.fillOpacity) != null ? _f : 1,
          strokeOpacity: (_h = (_g = marker.strokeOpacity) != null ? _g : strokeOpacity) != null ? _h : 1,
          strokeWidth: (_i = marker.strokeWidth) != null ? _i : 0,
          enabled: marker.enabled
        },
        line: {
          stroke: stroke != null ? stroke : color0,
          strokeOpacity,
          strokeWidth,
          lineDash
        }
      }
    ];
  }
  updatePaths(opts) {
    return __async(this, null, function* () {
      this.updateLinePaths([opts.paths], [opts.contextData]);
    });
  }
  updateLinePaths(paths, contextData) {
    contextData.forEach(({ nodeData }, contextDataIndex) => {
      const [lineNode] = paths[contextDataIndex];
      const { path: linePath } = lineNode;
      linePath.clear({ trackChanges: true });
      for (const data of nodeData) {
        if (data.point.moveTo) {
          linePath.moveTo(data.point.x, data.point.y);
        } else {
          linePath.lineTo(data.point.x, data.point.y);
        }
      }
      lineNode.checkPathDirty();
    });
  }
  animateEmptyUpdateReady(animationData) {
    const { markerSelections, labelSelections, annotationSelections, contextData, paths } = animationData;
    const { animationManager } = this.ctx;
    this.updateLinePaths(paths, contextData);
    pathSwipeInAnimation(this, animationManager, paths.flat());
    resetMotion(markerSelections, resetMarkerPositionFn);
    markerSwipeScaleInAnimation(this, animationManager, markerSelections);
    seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelections);
    seriesLabelFadeInAnimation(this, "annotations", animationManager, annotationSelections);
  }
  animateReadyResize(animationData) {
    const { contextData, paths } = animationData;
    this.updateLinePaths(paths, contextData);
    super.animateReadyResize(animationData);
  }
  animateWaitingUpdateReady(animationData) {
    var _a, _b;
    const { animationManager } = this.ctx;
    const { markerSelections, labelSelections, annotationSelections, contextData, paths, previousContextData } = animationData;
    super.resetAllAnimation(animationData);
    if (contextData.length === 0 || !previousContextData || previousContextData.length === 0) {
      animationManager.skipCurrentBatch();
      this.updateLinePaths(paths, contextData);
      return;
    }
    const [path] = paths;
    const [newData] = contextData;
    const [oldData] = previousContextData;
    const fns = prepareLinePathAnimation(newData, oldData, (_b = (_a = this.processedData) == null ? void 0 : _a.reduced) == null ? void 0 : _b.diff);
    if (fns === void 0) {
      animationManager.skipCurrentBatch();
      this.updateLinePaths(paths, contextData);
      return;
    }
    fromToMotion(this.id, "marker", animationManager, markerSelections, fns.marker);
    fromToMotion(this.id, "path_properties", animationManager, path, fns.pathProperties);
    pathMotion(this.id, "path_update", animationManager, path, fns.path);
    if (fns.hasMotion) {
      seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelections);
      seriesLabelFadeInAnimation(this, "annotations", animationManager, annotationSelections);
    }
  }
  getDatumId(datum) {
    return createDatumId([`${datum.xValue}`]);
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  getBandScalePadding() {
    return { inner: 1, outer: 0.1 };
  }
  nodeFactory() {
    return new Group();
  }
};
_LineSeries.className = "LineSeries";
_LineSeries.type = "line";
var LineSeries = _LineSeries;
var LineSeriesModule = {
  type: "series",
  optionsKey: "series[]",
  packageType: "community",
  chartTypes: ["cartesian"],
  identifier: "line",
  instanceConstructor: LineSeries,
  seriesDefaults: DEFAULT_CARTESIAN_CHART_OVERRIDES,
  themeTemplate: {
    __extends__: EXTENDS_SERIES_DEFAULTS,
    tooltip: {
      position: {
        type: "node"
      }
    },
    strokeWidth: 2,
    strokeOpacity: 1,
    lineDash: [0],
    lineDashOffset: 0,
    marker: {
      __extends__: EXTENDS_CARTESIAN_MARKER_DEFAULTS,
      fillOpacity: 1,
      strokeOpacity: 1,
      strokeWidth: 0
    },
    label: {
      enabled: false,
      fontStyle: void 0,
      fontWeight: void 0,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_LABEL_COLOUR,
      formatter: void 0
    }
  },
  enterpriseThemeTemplate: {
    errorBar: {
      cap: {
        lengthRatio: 1
      }
    }
  },
  paletteFactory: (params) => {
    const { marker } = markerPaletteFactory(params);
    return {
      stroke: marker.fill,
      marker
    };
  }
};
var ScatterSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.colorRange = ["#ffff00", "#00ff00", "#0000ff"];
    this.marker = new SeriesMarker();
    this.label = new Label();
    this.tooltip = new SeriesTooltip();
  }
};
__decorateClass([
  Validate(STRING)
], ScatterSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  Validate(STRING)
], ScatterSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], ScatterSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], ScatterSeriesProperties.prototype, "colorKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], ScatterSeriesProperties.prototype, "xName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], ScatterSeriesProperties.prototype, "yName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], ScatterSeriesProperties.prototype, "labelName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], ScatterSeriesProperties.prototype, "colorName", 2);
__decorateClass([
  Validate(NUMBER_ARRAY, { optional: true })
], ScatterSeriesProperties.prototype, "colorDomain", 2);
__decorateClass([
  Validate(COLOR_STRING_ARRAY)
], ScatterSeriesProperties.prototype, "colorRange", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], ScatterSeriesProperties.prototype, "title", 2);
__decorateClass([
  Validate(OBJECT)
], ScatterSeriesProperties.prototype, "marker", 2);
__decorateClass([
  Validate(OBJECT)
], ScatterSeriesProperties.prototype, "label", 2);
__decorateClass([
  Validate(OBJECT)
], ScatterSeriesProperties.prototype, "tooltip", 2);
var _ScatterSeries = class _ScatterSeries2 extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [
        2,
        3,
        0
        /* EXACT_SHAPE_MATCH */
      ],
      pathsPerSeries: 0,
      hasMarkers: true,
      markerSelectionGarbageCollection: false,
      animationResetFns: {
        marker: resetMarkerFn,
        label: resetLabelFn
      }
    });
    this.properties = new ScatterSeriesProperties();
    this.colorScale = new ColorScale();
  }
  processData(dataController) {
    return __async(this, null, function* () {
      var _a;
      if (!this.properties.isValid() || this.data == null) {
        return;
      }
      const { isContinuousX, isContinuousY } = this.isContinuous();
      const { xKey, yKey, labelKey, colorKey, colorDomain, colorRange } = this.properties;
      const { dataModel, processedData } = yield this.requestDataModel(dataController, this.data, {
        props: [
          keyProperty(this, xKey, isContinuousX, { id: "xKey-raw" }),
          keyProperty(this, yKey, isContinuousY, { id: "yKey-raw" }),
          ...labelKey ? [keyProperty(this, labelKey, false, { id: `labelKey-raw` })] : [],
          valueProperty(this, xKey, isContinuousX, { id: `xValue` }),
          valueProperty(this, yKey, isContinuousY, { id: `yValue` }),
          ...colorKey ? [valueProperty(this, colorKey, true, { id: `colorValue` })] : [],
          ...labelKey ? [valueProperty(this, labelKey, false, { id: `labelValue` })] : []
        ],
        dataVisible: this.visible
      });
      if (colorKey) {
        const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, `colorValue`).index;
        this.colorScale.domain = (_a = colorDomain != null ? colorDomain : processedData.domain.values[colorKeyIdx]) != null ? _a : [];
        this.colorScale.range = colorRange;
        this.colorScale.update();
      }
      this.animationState.transition("updateData");
    });
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData } = this;
    if (!processedData || !dataModel)
      return [];
    const id = direction === "x" ? `xValue` : `yValue`;
    const dataDef = dataModel.resolveProcessedDataDefById(this, id);
    const domain = dataModel.getDomain(this, id, "value", processedData);
    if ((dataDef == null ? void 0 : dataDef.def.type) === "value" && (dataDef == null ? void 0 : dataDef.def.valueType) === "category") {
      return domain;
    }
    const axis = this.axes[direction];
    return fixNumericExtent(extent(domain), axis);
  }
  createNodeData() {
    return __async(this, null, function* () {
      var _a, _b, _c;
      const { axes, dataModel, processedData, colorScale } = this;
      const { xKey, yKey, labelKey, colorKey, xName, yName, labelName, marker, label, visible } = this.properties;
      const xAxis = axes[
        "x"
        /* X */
      ];
      const yAxis = axes[
        "y"
        /* Y */
      ];
      if (!(dataModel && processedData && visible && xAxis && yAxis)) {
        return [];
      }
      const xDataIdx = dataModel.resolveProcessedDataIndexById(this, `xValue`).index;
      const yDataIdx = dataModel.resolveProcessedDataIndexById(this, `yValue`).index;
      const colorDataIdx = colorKey ? dataModel.resolveProcessedDataIndexById(this, `colorValue`).index : -1;
      const labelDataIdx = labelKey ? dataModel.resolveProcessedDataIndexById(this, `labelValue`).index : -1;
      const xScale = xAxis.scale;
      const yScale = yAxis.scale;
      const xOffset = ((_a = xScale.bandwidth) != null ? _a : 0) / 2;
      const yOffset = ((_b = yScale.bandwidth) != null ? _b : 0) / 2;
      const nodeData = [];
      const font = label.getFont();
      for (const { values, datum } of (_c = processedData.data) != null ? _c : []) {
        const xDatum = values[xDataIdx];
        const yDatum = values[yDataIdx];
        const x = xScale.convert(xDatum) + xOffset;
        const y = yScale.convert(yDatum) + yOffset;
        const labelText = this.getLabelText(label, {
          value: labelKey ? values[labelDataIdx] : yDatum,
          datum,
          xKey,
          yKey,
          labelKey,
          xName,
          yName,
          labelName
        });
        const size = HdpiCanvas.getTextSize(labelText, font);
        const fill = colorKey ? colorScale.convert(values[colorDataIdx]) : void 0;
        nodeData.push({
          series: this,
          itemId: yKey,
          yKey,
          xKey,
          datum,
          xValue: xDatum,
          yValue: yDatum,
          capDefaults: { lengthRatioMultiplier: marker.getDiameter(), lengthMax: Infinity },
          point: { x, y, size: marker.size },
          midPoint: { x, y },
          fill,
          label: __spreadValues({ text: labelText }, size)
        });
      }
      return [
        {
          itemId: yKey,
          nodeData,
          labelData: nodeData,
          scales: __superGet(_ScatterSeries2.prototype, this, "calculateScaling").call(this),
          visible: this.visible
        }
      ];
    });
  }
  isPathOrSelectionDirty() {
    return this.properties.marker.isDirty();
  }
  getLabelData() {
    var _a;
    return (_a = this.contextNodeData) == null ? void 0 : _a.reduce((r, n) => r.concat(n.labelData), []);
  }
  markerFactory() {
    const { shape } = this.properties.marker;
    const MarkerShape = getMarker(shape);
    return new MarkerShape();
  }
  updateMarkerSelection(opts) {
    return __async(this, null, function* () {
      const { nodeData, markerSelection } = opts;
      if (this.properties.marker.isDirty()) {
        markerSelection.clear();
        markerSelection.cleanup();
      }
      return markerSelection.update(this.properties.marker.enabled ? nodeData : []);
    });
  }
  updateMarkerNodes(opts) {
    return __async(this, null, function* () {
      const { markerSelection, isHighlight: highlighted } = opts;
      const { xKey, yKey, labelKey, marker, highlightStyle } = this.properties;
      const baseStyle = mergeDefaults(highlighted && highlightStyle.item, marker.getStyle());
      markerSelection.each((node, datum) => {
        this.updateMarkerStyle(node, marker, { datum, highlighted, xKey, yKey, labelKey }, baseStyle);
      });
      if (!highlighted) {
        marker.markClean();
      }
    });
  }
  updateLabelSelection(opts) {
    return __async(this, null, function* () {
      var _a, _b;
      const placedLabels = this.isLabelEnabled() ? (_b = (_a = this.chart) == null ? void 0 : _a.placeLabels().get(this)) != null ? _b : [] : [];
      return opts.labelSelection.update(
        placedLabels.map(({ datum, x, y }) => __spreadProps(__spreadValues({}, datum), {
          point: { x, y, size: datum.point.size }
        })),
        (text) => {
          text.pointerEvents = 1;
        }
      );
    });
  }
  updateLabelNodes(opts) {
    return __async(this, null, function* () {
      const { label } = this.properties;
      opts.labelSelection.each((text, datum) => {
        var _a, _b, _c, _d;
        text.text = datum.label.text;
        text.fill = label.color;
        text.x = (_b = (_a = datum.point) == null ? void 0 : _a.x) != null ? _b : 0;
        text.y = (_d = (_c = datum.point) == null ? void 0 : _c.y) != null ? _d : 0;
        text.fontStyle = label.fontStyle;
        text.fontWeight = label.fontWeight;
        text.fontSize = label.fontSize;
        text.fontFamily = label.fontFamily;
        text.textAlign = "left";
        text.textBaseline = "top";
      });
    });
  }
  getTooltipHtml(nodeDatum) {
    const xAxis = this.axes[
      "x"
      /* X */
    ];
    const yAxis = this.axes[
      "y"
      /* Y */
    ];
    if (!this.properties.isValid() || !xAxis || !yAxis) {
      return "";
    }
    const { xKey, yKey, labelKey, xName, yName, labelName, title = yName, marker, tooltip } = this.properties;
    const { datum, xValue, yValue, label } = nodeDatum;
    const baseStyle = mergeDefaults(
      { fill: nodeDatum.fill, strokeWidth: this.getStrokeWidth(marker.strokeWidth) },
      marker.getStyle()
    );
    const { fill: color = "gray" } = this.getMarkerStyle(
      marker,
      { datum: nodeDatum, highlighted: false, xKey, yKey, labelKey },
      baseStyle
    );
    const xString = sanitizeHtml(xAxis.formatDatum(xValue));
    const yString = sanitizeHtml(yAxis.formatDatum(yValue));
    let content = `<b>${sanitizeHtml(xName != null ? xName : xKey)}</b>: ${xString}<br><b>${sanitizeHtml(yName != null ? yName : yKey)}</b>: ${yString}`;
    if (labelKey) {
      content = `<b>${sanitizeHtml(labelName != null ? labelName : labelKey)}</b>: ${sanitizeHtml(label.text)}<br>` + content;
    }
    return tooltip.toTooltipHtml(
      { title, content, backgroundColor: color },
      __spreadValues({
        datum,
        xKey,
        xName,
        yKey,
        yName,
        labelKey,
        labelName,
        title,
        color,
        seriesId: this.id
      }, this.getModuleTooltipParams())
    );
  }
  getLegendData(legendType) {
    var _a, _b, _c, _d, _e, _f;
    const { yKey, yName, title, marker, visible } = this.properties;
    const { fill, stroke, fillOpacity, strokeOpacity, strokeWidth } = marker;
    if (!((_a = this.data) == null ? void 0 : _a.length) || !this.properties.isValid() || legendType !== "category") {
      return [];
    }
    return [
      {
        legendType: "category",
        id: this.id,
        itemId: yKey,
        seriesId: this.id,
        enabled: visible,
        label: {
          text: (_b = title != null ? title : yName) != null ? _b : yKey
        },
        marker: {
          shape: marker.shape,
          fill: (_d = (_c = marker.fill) != null ? _c : fill) != null ? _d : "rgba(0, 0, 0, 0)",
          stroke: (_f = (_e = marker.stroke) != null ? _e : stroke) != null ? _f : "rgba(0, 0, 0, 0)",
          fillOpacity: fillOpacity != null ? fillOpacity : 1,
          strokeOpacity: strokeOpacity != null ? strokeOpacity : 1,
          strokeWidth: strokeWidth != null ? strokeWidth : 0
        }
      }
    ];
  }
  animateEmptyUpdateReady(data) {
    const { markerSelections, labelSelections, annotationSelections } = data;
    markerScaleInAnimation(this, this.ctx.animationManager, markerSelections);
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelections);
    seriesLabelFadeInAnimation(this, "annotations", this.ctx.animationManager, annotationSelections);
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  nodeFactory() {
    return new Group();
  }
};
_ScatterSeries.className = "ScatterSeries";
_ScatterSeries.type = "scatter";
var ScatterSeries = _ScatterSeries;
var ScatterSeriesModule = {
  type: "series",
  optionsKey: "series[]",
  packageType: "community",
  chartTypes: ["cartesian"],
  identifier: "scatter",
  instanceConstructor: ScatterSeries,
  seriesDefaults: {
    axes: [
      { type: CARTESIAN_AXIS_TYPES.NUMBER, position: CARTESIAN_AXIS_POSITIONS.BOTTOM },
      { type: CARTESIAN_AXIS_TYPES.NUMBER, position: CARTESIAN_AXIS_POSITIONS.LEFT }
    ]
  },
  themeTemplate: {
    __extends__: EXTENDS_SERIES_DEFAULTS,
    tooltip: {
      position: {
        type: "node"
      }
    },
    marker: {
      __extends__: EXTENDS_CARTESIAN_MARKER_DEFAULTS,
      fillOpacity: 0.8
    },
    label: {
      enabled: false,
      fontStyle: void 0,
      fontWeight: void 0,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_LABEL_COLOUR
    }
  },
  enterpriseThemeTemplate: {
    errorBar: {
      cap: {
        lengthRatio: 1
      }
    }
  },
  paletteFactory: markerPaletteFactory
};
var DEFAULT_FILLS = {
  BLUE: "#5090dc",
  ORANGE: "#ffa03a",
  GREEN: "#459d55",
  CYAN: "#34bfe1",
  YELLOW: "#e1cc00",
  VIOLET: "#9669cb",
  GRAY: "#b5b5b5",
  MAGENTA: "#bd5aa7",
  BROWN: "#8a6224",
  RED: "#ef5452"
};
var DEFAULT_STROKES = {
  BLUE: "#2b5c95",
  ORANGE: "#cc6f10",
  GREEN: "#1e652e",
  CYAN: "#18859e",
  YELLOW: "#a69400",
  VIOLET: "#603c88",
  GRAY: "#575757",
  MAGENTA: "#7d2f6d",
  BROWN: "#4f3508",
  RED: "#a82529"
};
var PieTitle = class extends Caption {
  constructor() {
    super(...arguments);
    this.showInLegend = false;
  }
};
__decorateClass([
  Validate(BOOLEAN)
], PieTitle.prototype, "showInLegend", 2);
var DoughnutInnerLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.margin = 2;
  }
  set(properties, _reset) {
    return super.set(properties);
  }
};
__decorateClass([
  Validate(STRING)
], DoughnutInnerLabel.prototype, "text", 2);
__decorateClass([
  Validate(NUMBER)
], DoughnutInnerLabel.prototype, "margin", 2);
var DoughnutInnerCircle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = "transparent";
    this.fillOpacity = 1;
  }
};
__decorateClass([
  Validate(COLOR_STRING)
], DoughnutInnerCircle.prototype, "fill", 2);
__decorateClass([
  Validate(RATIO)
], DoughnutInnerCircle.prototype, "fillOpacity", 2);
var PieSeriesCalloutLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.offset = 3;
    this.minAngle = 0;
    this.minSpacing = 4;
    this.maxCollisionOffset = 50;
    this.avoidCollisions = true;
  }
};
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PieSeriesCalloutLabel.prototype, "offset", 2);
__decorateClass([
  Validate(DEGREE)
], PieSeriesCalloutLabel.prototype, "minAngle", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PieSeriesCalloutLabel.prototype, "minSpacing", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PieSeriesCalloutLabel.prototype, "maxCollisionOffset", 2);
__decorateClass([
  Validate(BOOLEAN)
], PieSeriesCalloutLabel.prototype, "avoidCollisions", 2);
var PieSeriesSectorLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.positionOffset = 0;
    this.positionRatio = 0.5;
  }
};
__decorateClass([
  Validate(NUMBER)
], PieSeriesSectorLabel.prototype, "positionOffset", 2);
__decorateClass([
  Validate(RATIO)
], PieSeriesSectorLabel.prototype, "positionRatio", 2);
var PieSeriesCalloutLine = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.length = 10;
    this.strokeWidth = 1;
  }
};
__decorateClass([
  Validate(COLOR_STRING_ARRAY, { optional: true })
], PieSeriesCalloutLine.prototype, "colors", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PieSeriesCalloutLine.prototype, "length", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PieSeriesCalloutLine.prototype, "strokeWidth", 2);
var PieSeriesProperties = class extends SeriesProperties {
  constructor() {
    super(...arguments);
    this.fills = Object.values(DEFAULT_FILLS);
    this.strokes = Object.values(DEFAULT_STROKES);
    this.fillOpacity = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.rotation = 0;
    this.outerRadiusOffset = 0;
    this.outerRadiusRatio = 1;
    this.innerRadiusOffset = 0;
    this.innerRadiusRatio = 1;
    this.strokeWidth = 1;
    this.sectorSpacing = void 0;
    this.innerLabels = new PropertiesArray(DoughnutInnerLabel);
    this.title = new PieTitle();
    this.innerCircle = new DoughnutInnerCircle();
    this.shadow = new DropShadow();
    this.calloutLabel = new PieSeriesCalloutLabel();
    this.sectorLabel = new PieSeriesSectorLabel();
    this.calloutLine = new PieSeriesCalloutLine();
    this.tooltip = new SeriesTooltip();
    this.__BACKGROUND_COLOR_DO_NOT_USE = void 0;
  }
};
__decorateClass([
  Validate(STRING)
], PieSeriesProperties.prototype, "angleKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "angleName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "radiusKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "radiusName", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], PieSeriesProperties.prototype, "radiusMin", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], PieSeriesProperties.prototype, "radiusMax", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "calloutLabelKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "calloutLabelName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "sectorLabelKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "sectorLabelName", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "legendItemKey", 2);
__decorateClass([
  Validate(COLOR_STRING_ARRAY)
], PieSeriesProperties.prototype, "fills", 2);
__decorateClass([
  Validate(COLOR_STRING_ARRAY)
], PieSeriesProperties.prototype, "strokes", 2);
__decorateClass([
  Validate(RATIO)
], PieSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  Validate(RATIO)
], PieSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  Validate(LINE_DASH)
], PieSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PieSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  Validate(FUNCTION, { optional: true })
], PieSeriesProperties.prototype, "formatter", 2);
__decorateClass([
  Validate(DEGREE)
], PieSeriesProperties.prototype, "rotation", 2);
__decorateClass([
  Validate(NUMBER)
], PieSeriesProperties.prototype, "outerRadiusOffset", 2);
__decorateClass([
  Validate(RATIO)
], PieSeriesProperties.prototype, "outerRadiusRatio", 2);
__decorateClass([
  Validate(NUMBER)
], PieSeriesProperties.prototype, "innerRadiusOffset", 2);
__decorateClass([
  Validate(RATIO)
], PieSeriesProperties.prototype, "innerRadiusRatio", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER)
], PieSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  Validate(POSITIVE_NUMBER, { optional: true })
], PieSeriesProperties.prototype, "sectorSpacing", 2);
__decorateClass([
  Validate(OBJECT_ARRAY)
], PieSeriesProperties.prototype, "innerLabels", 2);
__decorateClass([
  Validate(OBJECT)
], PieSeriesProperties.prototype, "title", 2);
__decorateClass([
  Validate(OBJECT)
], PieSeriesProperties.prototype, "innerCircle", 2);
__decorateClass([
  Validate(OBJECT)
], PieSeriesProperties.prototype, "shadow", 2);
__decorateClass([
  Validate(OBJECT)
], PieSeriesProperties.prototype, "calloutLabel", 2);
__decorateClass([
  Validate(OBJECT)
], PieSeriesProperties.prototype, "sectorLabel", 2);
__decorateClass([
  Validate(OBJECT)
], PieSeriesProperties.prototype, "calloutLine", 2);
__decorateClass([
  Validate(OBJECT)
], PieSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], PieSeriesProperties.prototype, "__BACKGROUND_COLOR_DO_NOT_USE", 2);
function preparePieSeriesAnimationFunctions(initialLoad, rotationDegrees, scaleFn, oldScaleFn) {
  const scale2 = [scaleFn.convert(0), scaleFn.convert(1)];
  const oldScale = [oldScaleFn.convert(0), oldScaleFn.convert(1)];
  const rotation = Math.PI / -2 + toRadians(rotationDegrees);
  const scaleToNewRadius = ({ radius }) => {
    return { innerRadius: scale2[0], outerRadius: scale2[0] + (scale2[1] - scale2[0]) * radius };
  };
  const scaleToOldRadius = ({ radius }) => {
    return { innerRadius: oldScale[0], outerRadius: oldScale[0] + (oldScale[1] - oldScale[0]) * radius };
  };
  const fromFn = (sect, datum, status, { prevFromProps }) => {
    var _a, _b, _c, _d, _e, _f;
    let { startAngle, endAngle, innerRadius, outerRadius } = sect;
    let { fill, stroke } = datum.sectorFormat;
    if (status === "unknown" || status === "added" && !prevFromProps) {
      startAngle = rotation;
      endAngle = rotation;
      innerRadius = datum.innerRadius;
      outerRadius = datum.outerRadius;
    } else if (status === "added" && prevFromProps) {
      startAngle = (_a = prevFromProps.endAngle) != null ? _a : rotation;
      endAngle = (_b = prevFromProps.endAngle) != null ? _b : rotation;
      innerRadius = (_c = prevFromProps.innerRadius) != null ? _c : datum.innerRadius;
      outerRadius = (_d = prevFromProps.outerRadius) != null ? _d : datum.outerRadius;
    }
    if (status === "added" && !initialLoad) {
      const radii = scaleToOldRadius(datum);
      innerRadius = radii.innerRadius;
      outerRadius = radii.outerRadius;
    }
    if (status === "updated") {
      fill = (_e = sect.fill) != null ? _e : fill;
      stroke = (_f = sect.stroke) != null ? _f : stroke;
    }
    return { startAngle, endAngle, innerRadius, outerRadius, fill, stroke };
  };
  const toFn = (_sect, datum, status, { prevLive }) => {
    var _a, _b;
    let { startAngle, endAngle, innerRadius, outerRadius } = datum;
    const { stroke, fill } = datum.sectorFormat;
    if (status === "removed" && prevLive) {
      startAngle = (_a = prevLive.datum) == null ? void 0 : _a.endAngle;
      endAngle = (_b = prevLive.datum) == null ? void 0 : _b.endAngle;
    } else if (status === "removed" && !prevLive) {
      startAngle = rotation;
      endAngle = rotation;
    }
    if (status === "removed") {
      const radii = scaleToNewRadius(datum);
      innerRadius = radii.innerRadius;
      outerRadius = radii.outerRadius;
    }
    return { startAngle, endAngle, outerRadius, innerRadius, stroke, fill };
  };
  const innerCircle = {
    fromFn: (node, _datum) => {
      var _a, _b, _c;
      return { size: (_c = (_b = (_a = node.previousDatum) == null ? void 0 : _a.radius) != null ? _b : node.size) != null ? _c : 0 };
    },
    toFn: (_node, datum) => {
      var _a;
      return { size: (_a = datum.radius) != null ? _a : 0 };
    }
  };
  return { nodes: { toFn, fromFn }, innerCircle };
}
function resetPieSelectionsFn(_node, datum) {
  return {
    startAngle: datum.startAngle,
    endAngle: datum.endAngle,
    innerRadius: datum.innerRadius,
    outerRadius: datum.outerRadius,
    fill: datum.sectorFormat.fill,
    stroke: datum.sectorFormat.stroke
  };
}
var PolarSeries = class extends DataModelSeries {
  constructor(_a) {
    var _b = _a, {
      useLabelLayer = false,
      pickModes = [
        0
        /* EXACT_SHAPE_MATCH */
      ],
      canHaveAxes = false,
      animationResetFns
    } = _b, opts = __objRest(_b, [
      "useLabelLayer",
      "pickModes",
      "canHaveAxes",
      "animationResetFns"
    ]);
    super(__spreadProps(__spreadValues({}, opts), {
      useLabelLayer,
      pickModes,
      contentGroupVirtual: false,
      directionKeys: {
        [
          "x"
          /* X */
        ]: ["angleKey"],
        [
          "y"
          /* Y */
        ]: ["radiusKey"]
      },
      directionNames: {
        [
          "x"
          /* X */
        ]: ["angleName"],
        [
          "y"
          /* Y */
        ]: ["radiusName"]
      },
      canHaveAxes
    }));
    this.sectorGroup = this.contentGroup.appendChild(new Group());
    this.itemSelection = Selection.select(
      this.sectorGroup,
      () => this.nodeFactory(),
      false
    );
    this.labelSelection = Selection.select(this.labelGroup, Text, false);
    this.highlightSelection = Selection.select(
      this.highlightGroup,
      () => this.nodeFactory()
    );
    this.centerX = 0;
    this.centerY = 0;
    this.radius = 0;
    this.sectorGroup.zIndexSubOrder = [() => this._declarationOrder, 1];
    this.animationResetFns = animationResetFns;
    this.animationState = new StateMachine(
      "empty",
      {
        empty: {
          update: {
            target: "ready",
            action: (data) => this.animateEmptyUpdateReady(data)
          }
        },
        ready: {
          updateData: "waiting",
          clear: "clearing",
          highlight: (data) => this.animateReadyHighlight(data),
          highlightMarkers: (data) => this.animateReadyHighlightMarkers(data),
          resize: (data) => this.animateReadyResize(data)
        },
        waiting: {
          update: {
            target: "ready",
            action: (data) => this.animateWaitingUpdateReady(data)
          }
        },
        clearing: {
          update: {
            target: "empty",
            action: (data) => this.animateClearingUpdateEmpty(data)
          }
        }
      },
      () => this.checkProcessedDataAnimatable()
    );
  }
  getLabelData() {
    return [];
  }
  computeLabelsBBox(_options, _seriesRect) {
    return null;
  }
  resetAllAnimation() {
    var _a;
    const { item, label } = (_a = this.animationResetFns) != null ? _a : {};
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    if (item) {
      resetMotion([this.itemSelection, this.highlightSelection], item);
    }
    if (label) {
      resetMotion([this.labelSelection], label);
    }
    this.itemSelection.cleanup();
    this.labelSelection.cleanup();
    this.highlightSelection.cleanup();
  }
  animateEmptyUpdateReady(_data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation();
  }
  animateWaitingUpdateReady(_data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation();
  }
  animateReadyHighlight(_data) {
    var _a;
    const { item } = (_a = this.animationResetFns) != null ? _a : {};
    if (item) {
      resetMotion([this.highlightSelection], item);
    }
  }
  animateReadyHighlightMarkers(_data) {
  }
  animateReadyResize(_data) {
    this.resetAllAnimation();
  }
  animateClearingUpdateEmpty(_data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation();
  }
  animationTransitionClear() {
    this.animationState.transition("clear", this.getAnimationData());
  }
  getAnimationData(seriesRect) {
    return { seriesRect };
  }
};
var PieSeriesNodeClickEvent = class extends SeriesNodeClickEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.angleKey = series.properties.angleKey;
    this.radiusKey = series.properties.radiusKey;
    this.calloutLabelKey = series.properties.calloutLabelKey;
    this.sectorLabelKey = series.properties.sectorLabelKey;
  }
};
var PieSeries = class extends PolarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      useLabelLayer: true,
      animationResetFns: { item: resetPieSelectionsFn, label: resetLabelFn }
    });
    this.properties = new PieSeriesProperties();
    this.previousRadiusScale = new LinearScale();
    this.radiusScale = new LinearScale();
    this.backgroundGroup = this.rootGroup.appendChild(
      new Group({
        name: `${this.id}-background`,
        layer: true,
        zIndex: 0
        /* SERIES_BACKGROUND_ZINDEX */
      })
    );
    this.zerosumRingsGroup = this.backgroundGroup.appendChild(new Group({ name: `${this.id}-zerosumRings` }));
    this.zerosumOuterRing = this.zerosumRingsGroup.appendChild(new Circle());
    this.zerosumInnerRing = this.zerosumRingsGroup.appendChild(new Circle());
    this.innerCircleGroup = this.backgroundGroup.appendChild(new Group({ name: `${this.id}-innerCircle` }));
    this.nodeData = [];
    this.seriesItemEnabled = [];
    this.surroundingRadius = void 0;
    this.NodeClickEvent = PieSeriesNodeClickEvent;
    this.angleScale = new LinearScale();
    this.angleScale.domain = [0, 1];
    this.angleScale.range = [-Math.PI, Math.PI].map((angle) => angle + Math.PI / 2);
    const pieCalloutLabels = new Group({ name: "pieCalloutLabels" });
    const pieSectorLabels = new Group({ name: "pieSectorLabels" });
    const innerLabels = new Group({ name: "innerLabels" });
    this.labelGroup.append(pieCalloutLabels);
    this.labelGroup.append(pieSectorLabels);
    this.labelGroup.append(innerLabels);
    this.calloutLabelSelection = Selection.select(pieCalloutLabels, Group);
    this.sectorLabelSelection = Selection.select(pieSectorLabels, Text);
    this.innerLabelsSelection = Selection.select(innerLabels, Text);
    this.innerCircleSelection = Selection.select(this.innerCircleGroup, Circle);
    for (const circle of [this.zerosumInnerRing, this.zerosumOuterRing]) {
      circle.fillOpacity = 0;
      circle.stroke = this.properties.calloutLabel.color;
      circle.strokeWidth = 1;
      circle.strokeOpacity = 1;
    }
  }
  addChartEventListeners() {
    var _a;
    (_a = this.ctx.chartEventManager) == null ? void 0 : _a.addListener("legend-item-click", (event) => this.onLegendItemClick(event));
  }
  visibleChanged() {
    this.processSeriesItemEnabled();
  }
  get visible() {
    return this.seriesItemEnabled.length ? this.seriesItemEnabled.some((visible) => visible) : super.visible;
  }
  processSeriesItemEnabled() {
    var _a;
    const { data, visible } = this;
    this.seriesItemEnabled = (_a = data == null ? void 0 : data.map(() => visible)) != null ? _a : [];
  }
  nodeFactory() {
    return new Sector();
  }
  getSeriesDomain(direction) {
    if (direction === "x") {
      return this.angleScale.domain;
    } else {
      return this.radiusScale.domain;
    }
  }
  processData(dataController) {
    return __async(this, null, function* () {
      var _a, _b, _c, _d, _e;
      if (this.data == null || !this.properties.isValid()) {
        return;
      }
      let { data } = this;
      const { seriesItemEnabled } = this;
      const { angleKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties;
      const animationEnabled = !this.ctx.animationManager.isSkipped();
      const extraKeyProps = [];
      const extraProps = [];
      if (legendItemKey) {
        extraKeyProps.push(keyProperty(this, legendItemKey, false, { id: `legendItemKey` }));
      } else if (calloutLabelKey) {
        extraKeyProps.push(keyProperty(this, calloutLabelKey, false, { id: `calloutLabelKey` }));
      } else if (sectorLabelKey) {
        extraKeyProps.push(keyProperty(this, sectorLabelKey, false, { id: `sectorLabelKey` }));
      }
      if (radiusKey) {
        extraProps.push(
          rangedValueProperty(this, radiusKey, {
            id: "radiusValue",
            min: (_a = this.properties.radiusMin) != null ? _a : 0,
            max: this.properties.radiusMax
          }),
          valueProperty(this, radiusKey, true, { id: `radiusRaw` }),
          // Raw value pass-through.
          normalisePropertyTo(
            this,
            { id: "radiusValue" },
            [0, 1],
            1,
            (_b = this.properties.radiusMin) != null ? _b : 0,
            this.properties.radiusMax
          )
        );
      }
      if (calloutLabelKey) {
        extraProps.push(valueProperty(this, calloutLabelKey, false, { id: `calloutLabelValue` }));
      }
      if (sectorLabelKey) {
        extraProps.push(valueProperty(this, sectorLabelKey, false, { id: `sectorLabelValue` }));
      }
      if (legendItemKey) {
        extraProps.push(valueProperty(this, legendItemKey, false, { id: `legendItemValue` }));
      }
      if (animationEnabled && this.processedData && extraKeyProps.length > 0) {
        extraProps.push(diff(this.processedData));
      }
      extraProps.push(animationValidation(this));
      data = data.map((d, idx) => seriesItemEnabled[idx] ? d : __spreadProps(__spreadValues({}, d), { [angleKey]: 0 }));
      yield this.requestDataModel(dataController, data, {
        props: [
          ...extraKeyProps,
          accumulativeValueProperty(this, angleKey, true, { id: `angleValue`, onlyPositive: true }),
          valueProperty(this, angleKey, true, { id: `angleRaw` }),
          // Raw value pass-through.
          normalisePropertyTo(this, { id: "angleValue" }, [0, 1], 0, 0),
          ...extraProps
        ]
      });
      for (const valueDef of (_e = (_d = (_c = this.processedData) == null ? void 0 : _c.defs) == null ? void 0 : _d.values) != null ? _e : []) {
        const { id, missing, property } = valueDef;
        if (id !== "angleRaw" && missing !== void 0 && missing > 0) {
          Logger.warnOnce(
            `no value was found for the key '${String(property)}' on ${missing} data element${missing > 1 ? "s" : ""}`
          );
        }
      }
      this.animationState.transition("updateData");
    });
  }
  maybeRefreshNodeData() {
    return __async(this, null, function* () {
      if (!this.nodeDataRefresh)
        return;
      const [{ nodeData = [] } = {}] = yield this.createNodeData();
      this.nodeData = nodeData;
      this.nodeDataRefresh = false;
    });
  }
  getProcessedDataIndexes(dataModel) {
    const angleIdx = dataModel.resolveProcessedDataIndexById(this, `angleValue`).index;
    const radiusIdx = this.properties.radiusKey ? dataModel.resolveProcessedDataIndexById(this, `radiusValue`).index : -1;
    const calloutLabelIdx = this.properties.calloutLabelKey ? dataModel.resolveProcessedDataIndexById(this, `calloutLabelValue`).index : -1;
    const sectorLabelIdx = this.properties.sectorLabelKey ? dataModel.resolveProcessedDataIndexById(this, `sectorLabelValue`).index : -1;
    const legendItemIdx = this.properties.legendItemKey ? dataModel.resolveProcessedDataIndexById(this, `legendItemValue`).index : -1;
    return { angleIdx, radiusIdx, calloutLabelIdx, sectorLabelIdx, legendItemIdx };
  }
  createNodeData() {
    return __async(this, null, function* () {
      const { id: seriesId, processedData, dataModel, angleScale } = this;
      const { rotation } = this.properties;
      if (!processedData || !dataModel || processedData.type !== "ungrouped")
        return [];
      const { angleIdx, radiusIdx, calloutLabelIdx, sectorLabelIdx, legendItemIdx } = this.getProcessedDataIndexes(dataModel);
      let currentStart = 0;
      let sum2 = 0;
      const nodeData = processedData.data.map((group2, index) => {
        var _a;
        const { datum, values } = group2;
        const currentValue = values[angleIdx];
        const startAngle = angleScale.convert(currentStart) + toRadians(rotation);
        currentStart = currentValue;
        sum2 += currentValue;
        const endAngle = angleScale.convert(currentStart) + toRadians(rotation);
        const span = Math.abs(endAngle - startAngle);
        const midAngle = startAngle + span / 2;
        const angleValue = values[angleIdx + 1];
        const radius = radiusIdx >= 0 ? (_a = values[radiusIdx]) != null ? _a : 1 : 1;
        const radiusValue = radiusIdx >= 0 ? values[radiusIdx + 1] : void 0;
        const legendItemValue = legendItemIdx >= 0 ? values[legendItemIdx] : void 0;
        const labels = this.getLabels(
          datum,
          midAngle,
          span,
          true,
          values[calloutLabelIdx],
          values[sectorLabelIdx],
          legendItemValue
        );
        const sectorFormat = this.getSectorFormat(datum, index, false);
        return __spreadValues({
          itemId: index,
          series: this,
          datum,
          index,
          angleValue,
          midAngle,
          midCos: Math.cos(midAngle),
          midSin: Math.sin(midAngle),
          startAngle,
          endAngle,
          sectorFormat,
          radiusValue,
          radius,
          innerRadius: Math.max(this.radiusScale.convert(0), 0),
          outerRadius: Math.max(this.radiusScale.convert(radius), 0),
          legendItemValue
        }, labels);
      });
      this.zerosumOuterRing.visible = sum2 === 0;
      this.zerosumInnerRing.visible = sum2 === 0 && this.properties.innerRadiusRatio !== 1 && this.properties.innerRadiusRatio > 0;
      return [{ itemId: seriesId, nodeData, labelData: nodeData }];
    });
  }
  getLabels(datum, midAngle, span, skipDisabled, calloutLabelValue, sectorLabelValue, legendItemValue) {
    const { calloutLabel, sectorLabel, legendItemKey } = this.properties;
    const calloutLabelKey = !skipDisabled || calloutLabel.enabled ? this.properties.calloutLabelKey : void 0;
    const sectorLabelKey = !skipDisabled || sectorLabel.enabled ? this.properties.sectorLabelKey : void 0;
    if (!calloutLabelKey && !sectorLabelKey && !legendItemKey) {
      return {};
    }
    const labelFormatterParams = {
      datum,
      angleKey: this.properties.angleKey,
      angleName: this.properties.angleName,
      radiusKey: this.properties.radiusKey,
      radiusName: this.properties.radiusName,
      calloutLabelKey: this.properties.calloutLabelKey,
      calloutLabelName: this.properties.calloutLabelName,
      sectorLabelKey: this.properties.sectorLabelKey,
      sectorLabelName: this.properties.sectorLabelName,
      legendItemKey: this.properties.legendItemKey
    };
    const result = {};
    if (calloutLabelKey && span > toRadians(calloutLabel.minAngle)) {
      result.calloutLabel = __spreadProps(__spreadValues({}, this.getTextAlignment(midAngle)), {
        text: this.getLabelText(calloutLabel, __spreadProps(__spreadValues({}, labelFormatterParams), {
          value: calloutLabelValue
        })),
        hidden: false,
        collisionTextAlign: void 0,
        collisionOffsetY: 0,
        box: void 0
      });
    }
    if (sectorLabelKey) {
      result.sectorLabel = {
        text: this.getLabelText(sectorLabel, __spreadProps(__spreadValues({}, labelFormatterParams), {
          value: sectorLabelValue
        }))
      };
    }
    if (legendItemKey != null && legendItemValue != null) {
      result.legendItem = { key: legendItemKey, text: legendItemValue };
    }
    return result;
  }
  getTextAlignment(midAngle) {
    const quadrantTextOpts = [
      { textAlign: "center", textBaseline: "bottom" },
      { textAlign: "left", textBaseline: "middle" },
      { textAlign: "center", textBaseline: "hanging" },
      { textAlign: "right", textBaseline: "middle" }
    ];
    const midAngle180 = normalizeAngle180(midAngle);
    const quadrantStart = -3 * Math.PI / 4;
    const quadrantOffset = midAngle180 - quadrantStart;
    const quadrant = Math.floor(quadrantOffset / (Math.PI / 2));
    const quadrantIndex = mod(quadrant, quadrantTextOpts.length);
    return quadrantTextOpts[quadrantIndex];
  }
  getSectorFormat(datum, formatIndex, highlight) {
    var _a, _b, _c, _d, _e;
    const { callbackCache, highlightManager } = this.ctx;
    const { angleKey, radiusKey, fills, strokes, formatter, sectorSpacing, __BACKGROUND_COLOR_DO_NOT_USE } = this.properties;
    const highlightedDatum = highlightManager.getActiveHighlight();
    const isDatumHighlighted = highlight && (highlightedDatum == null ? void 0 : highlightedDatum.series) === this && formatIndex === highlightedDatum.itemId;
    const { fill, fillOpacity, stroke, strokeWidth, strokeOpacity } = mergeDefaults(
      isDatumHighlighted && this.properties.highlightStyle.item,
      {
        fill: fills.length > 0 ? fills[formatIndex % fills.length] : void 0,
        fillOpacity: this.properties.fillOpacity,
        // @todo(AG-10275) Remove sectorSpacing null case
        stroke: sectorSpacing != null ? strokes.length > 0 ? strokes[formatIndex % strokes.length] : void 0 : strokes.length > 0 ? strokes[formatIndex % strokes.length] : __BACKGROUND_COLOR_DO_NOT_USE,
        strokeWidth: this.getStrokeWidth(this.properties.strokeWidth),
        strokeOpacity: this.getOpacity()
      }
    );
    let format2;
    if (formatter) {
      format2 = callbackCache.call(formatter, {
        datum,
        angleKey,
        radiusKey,
        fill,
        stroke,
        fills,
        strokes,
        strokeWidth,
        highlighted: isDatumHighlighted,
        seriesId: this.id
      });
    }
    return {
      fill: (_a = format2 == null ? void 0 : format2.fill) != null ? _a : fill,
      fillOpacity: (_b = format2 == null ? void 0 : format2.fillOpacity) != null ? _b : fillOpacity,
      stroke: (_c = format2 == null ? void 0 : format2.stroke) != null ? _c : stroke,
      strokeWidth: (_d = format2 == null ? void 0 : format2.strokeWidth) != null ? _d : strokeWidth,
      strokeOpacity: (_e = format2 == null ? void 0 : format2.strokeOpacity) != null ? _e : strokeOpacity
    };
  }
  getInnerRadius() {
    const { radius } = this;
    const { innerRadiusRatio, innerRadiusOffset } = this.properties;
    const innerRadius = radius * innerRadiusRatio + innerRadiusOffset;
    if (innerRadius === radius || innerRadius < 0) {
      return 0;
    }
    return innerRadius;
  }
  getOuterRadius() {
    return Math.max(this.radius * this.properties.outerRadiusRatio + this.properties.outerRadiusOffset, 0);
  }
  updateRadiusScale(resize) {
    const newRange = [this.getInnerRadius(), this.getOuterRadius()];
    this.radiusScale.range = newRange;
    if (resize) {
      this.previousRadiusScale.range = newRange;
    }
    this.nodeData = this.nodeData.map((_a) => {
      var _b = _a, { radius } = _b, d = __objRest(_b, ["radius"]);
      return __spreadProps(__spreadValues({}, d), {
        radius,
        innerRadius: Math.max(this.radiusScale.convert(0), 0),
        outerRadius: Math.max(this.radiusScale.convert(radius), 0)
      });
    });
  }
  getTitleTranslationY() {
    var _a, _b;
    const outerRadius = Math.max(0, this.radiusScale.range[1]);
    if (outerRadius === 0) {
      return NaN;
    }
    const spacing = (_b = (_a = this.properties.title) == null ? void 0 : _a.spacing) != null ? _b : 0;
    const titleOffset = 2 + spacing;
    const dy = Math.max(0, -outerRadius);
    return -outerRadius - titleOffset - dy;
  }
  update(_0) {
    return __async(this, arguments, function* ({ seriesRect }) {
      const { title } = this.properties;
      const newNodeDataDependencies = {
        seriesRectWidth: seriesRect == null ? void 0 : seriesRect.width,
        seriesRectHeight: seriesRect == null ? void 0 : seriesRect.height
      };
      const resize = jsonDiff(this.nodeDataDependencies, newNodeDataDependencies) != null;
      if (resize) {
        this._nodeDataDependencies = newNodeDataDependencies;
      }
      yield this.maybeRefreshNodeData();
      this.updateTitleNodes();
      this.updateRadiusScale(resize);
      this.contentGroup.translationX = this.centerX;
      this.contentGroup.translationY = this.centerY;
      this.highlightGroup.translationX = this.centerX;
      this.highlightGroup.translationY = this.centerY;
      this.backgroundGroup.translationX = this.centerX;
      this.backgroundGroup.translationY = this.centerY;
      if (this.labelGroup) {
        this.labelGroup.translationX = this.centerX;
        this.labelGroup.translationY = this.centerY;
      }
      if (title) {
        const dy = this.getTitleTranslationY();
        const titleBox = title.node.computeBBox();
        title.node.visible = title.enabled && isFinite(dy) && !this.bboxIntersectsSurroundingSeries(titleBox, 0, dy);
        title.node.translationY = isFinite(dy) ? dy : 0;
      }
      this.updateNodeMidPoint();
      yield this.updateSelections();
      yield this.updateNodes(seriesRect);
    });
  }
  updateTitleNodes() {
    var _a, _b;
    const { oldTitle } = this;
    const { title } = this.properties;
    if (oldTitle !== title) {
      if (oldTitle) {
        (_a = this.labelGroup) == null ? void 0 : _a.removeChild(oldTitle.node);
      }
      if (title) {
        title.node.textBaseline = "bottom";
        (_b = this.labelGroup) == null ? void 0 : _b.appendChild(title.node);
      }
      this.oldTitle = title;
    }
  }
  updateNodeMidPoint() {
    this.nodeData.forEach((d) => {
      const radius = d.innerRadius + (d.outerRadius - d.innerRadius) / 2;
      d.midPoint = {
        x: d.midCos * Math.max(0, radius),
        y: d.midSin * Math.max(0, radius)
      };
    });
  }
  updateSelections() {
    return __async(this, null, function* () {
      yield this.updateGroupSelection();
      this.updateInnerCircleSelection();
    });
  }
  updateGroupSelection() {
    return __async(this, null, function* () {
      const { itemSelection, highlightSelection, calloutLabelSelection, sectorLabelSelection, innerLabelsSelection } = this;
      const update = (selection, clone) => {
        let nodeData = this.nodeData;
        if (clone) {
          nodeData = nodeData.map((datum) => __spreadProps(__spreadValues({}, datum), { sectorFormat: __spreadValues({}, datum.sectorFormat) }));
        }
        selection.update(nodeData);
        if (this.ctx.animationManager.isSkipped()) {
          selection.cleanup();
        }
      };
      update(itemSelection, false);
      update(highlightSelection, true);
      calloutLabelSelection.update(this.nodeData, (group2) => {
        const line = new Line();
        line.tag = 1;
        line.pointerEvents = 1;
        group2.appendChild(line);
        const text = new Text();
        text.tag = 2;
        text.pointerEvents = 1;
        group2.appendChild(text);
      });
      sectorLabelSelection.update(this.nodeData, (node) => {
        node.pointerEvents = 1;
      });
      innerLabelsSelection.update(this.properties.innerLabels, (node) => {
        node.pointerEvents = 1;
      });
    });
  }
  updateInnerCircleSelection() {
    const { innerCircle } = this.properties;
    let radius = 0;
    const innerRadius = this.getInnerRadius();
    if (innerRadius > 0) {
      const circleRadius = Math.min(innerRadius, this.getOuterRadius());
      const antiAliasingPadding = 1;
      radius = Math.ceil(circleRadius * 2 + antiAliasingPadding);
    }
    const datums = innerCircle ? [{ radius }] : [];
    this.innerCircleSelection.update(datums);
  }
  updateNodes(seriesRect) {
    return __async(this, null, function* () {
      const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
      const isVisible = this.seriesItemEnabled.indexOf(true) >= 0;
      this.rootGroup.visible = isVisible;
      this.backgroundGroup.visible = isVisible;
      this.contentGroup.visible = isVisible;
      this.highlightGroup.visible = isVisible && (highlightedDatum == null ? void 0 : highlightedDatum.series) === this;
      if (this.labelGroup) {
        this.labelGroup.visible = isVisible;
      }
      this.contentGroup.opacity = this.getOpacity();
      this.innerCircleSelection.each((node, { radius }) => {
        var _a, _b;
        node.setProperties({
          fill: (_a = this.properties.innerCircle) == null ? void 0 : _a.fill,
          opacity: (_b = this.properties.innerCircle) == null ? void 0 : _b.fillOpacity,
          size: radius
        });
      });
      const updateSectorFn = (sector, datum, _index, isDatumHighlighted) => {
        const format2 = this.getSectorFormat(datum.datum, datum.itemId, isDatumHighlighted);
        datum.sectorFormat.fill = format2.fill;
        datum.sectorFormat.stroke = format2.stroke;
        const animationDisabled = this.ctx.animationManager.isSkipped();
        if (animationDisabled) {
          sector.startAngle = datum.startAngle;
          sector.endAngle = datum.endAngle;
          sector.innerRadius = datum.innerRadius;
          sector.outerRadius = datum.outerRadius;
        }
        if (isDatumHighlighted || animationDisabled) {
          sector.fill = format2.fill;
          sector.stroke = format2.stroke;
        }
        sector.strokeWidth = format2.strokeWidth;
        sector.fillOpacity = format2.fillOpacity;
        sector.strokeOpacity = this.properties.strokeOpacity;
        sector.lineDash = this.properties.lineDash;
        sector.lineDashOffset = this.properties.lineDashOffset;
        sector.fillShadow = this.properties.shadow;
        sector.inset = this.properties.sectorSpacing != null ? (this.properties.sectorSpacing + (format2.stroke != null ? format2.strokeWidth : 0)) / 2 : 0;
        sector.lineJoin = this.properties.sectorSpacing != null ? "miter" : "round";
      };
      this.itemSelection.each((node, datum, index) => updateSectorFn(node, datum, index, false));
      this.highlightSelection.each((node, datum, index) => {
        const isDatumHighlighted = (highlightedDatum == null ? void 0 : highlightedDatum.series) === this && node.datum.itemId === highlightedDatum.itemId;
        updateSectorFn(node, datum, index, isDatumHighlighted);
        node.visible = isDatumHighlighted;
      });
      this.updateCalloutLineNodes();
      this.updateCalloutLabelNodes(seriesRect);
      this.updateSectorLabelNodes();
      this.updateInnerLabelNodes();
      this.updateZerosumRings();
      this.animationState.transition("update");
    });
  }
  updateCalloutLineNodes() {
    var _a;
    const { calloutLine } = this.properties;
    const calloutLength = calloutLine.length;
    const calloutStrokeWidth = calloutLine.strokeWidth;
    const calloutColors = (_a = calloutLine.colors) != null ? _a : this.properties.strokes;
    const { offset: offset4 } = this.properties.calloutLabel;
    this.calloutLabelSelection.selectByTag(
      1
      /* Callout */
    ).forEach((line, index) => {
      const datum = line.datum;
      const { calloutLabel: label, outerRadius } = datum;
      if ((label == null ? void 0 : label.text) && !label.hidden && outerRadius !== 0) {
        line.visible = true;
        line.strokeWidth = calloutStrokeWidth;
        line.stroke = calloutColors[index % calloutColors.length];
        line.fill = void 0;
        const x1 = datum.midCos * outerRadius;
        const y1 = datum.midSin * outerRadius;
        let x2 = datum.midCos * (outerRadius + calloutLength);
        let y2 = datum.midSin * (outerRadius + calloutLength);
        const isMoved = label.collisionTextAlign || label.collisionOffsetY !== 0;
        if (isMoved && label.box != null) {
          const box = label.box;
          let cx = x2;
          let cy = y2;
          if (x2 < box.x) {
            cx = box.x;
          } else if (x2 > box.x + box.width) {
            cx = box.x + box.width;
          }
          if (y2 < box.y) {
            cy = box.y;
          } else if (y2 > box.y + box.height) {
            cy = box.y + box.height;
          }
          const dx = cx - x2;
          const dy = cy - y2;
          const length = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
          const paddedLength = length - offset4;
          if (paddedLength > 0) {
            x2 = x2 + dx * paddedLength / length;
            y2 = y2 + dy * paddedLength / length;
          }
        }
        line.x1 = x1;
        line.y1 = y1;
        line.x2 = x2;
        line.y2 = y2;
      } else {
        line.visible = false;
      }
    });
  }
  getLabelOverflow(text, box, seriesRect) {
    const seriesLeft = seriesRect.x - this.centerX;
    const seriesRight = seriesRect.x + seriesRect.width - this.centerX;
    const seriesTop = seriesRect.y - this.centerY;
    const seriesBottom = seriesRect.y + seriesRect.height - this.centerY;
    const errPx = 1;
    let visibleTextPart = 1;
    if (box.x + errPx < seriesLeft) {
      visibleTextPart = (box.x + box.width - seriesLeft) / box.width;
    } else if (box.x + box.width - errPx > seriesRight) {
      visibleTextPart = (seriesRight - box.x) / box.width;
    }
    const hasVerticalOverflow = box.y + errPx < seriesTop || box.y + box.height - errPx > seriesBottom;
    const textLength = visibleTextPart === 1 ? text.length : Math.floor(text.length * visibleTextPart) - 1;
    const hasSurroundingSeriesOverflow = this.bboxIntersectsSurroundingSeries(box);
    return { textLength, hasVerticalOverflow, hasSurroundingSeriesOverflow };
  }
  bboxIntersectsSurroundingSeries(box, dx = 0, dy = 0) {
    const { surroundingRadius } = this;
    if (surroundingRadius == null) {
      return false;
    }
    const corners = [
      { x: box.x + dx, y: box.y + dy },
      { x: box.x + box.width + dx, y: box.y + dy },
      { x: box.x + box.width + dx, y: box.y + box.height + dy },
      { x: box.x + dx, y: box.y + box.height + dy }
    ];
    const sur2 = __pow(surroundingRadius, 2);
    return corners.some((corner) => __pow(corner.x, 2) + __pow(corner.y, 2) > sur2);
  }
  computeCalloutLabelCollisionOffsets() {
    const { radiusScale } = this;
    const { calloutLabel, calloutLine } = this.properties;
    const { offset: offset4, minSpacing } = calloutLabel;
    const innerRadius = radiusScale.convert(0);
    const shouldSkip = (datum) => {
      const label = datum.calloutLabel;
      return !label || datum.outerRadius === 0;
    };
    const fullData = this.nodeData;
    const data = this.nodeData.filter((t) => !shouldSkip(t));
    data.forEach((datum) => {
      const label = datum.calloutLabel;
      if (label == null)
        return;
      label.hidden = false;
      label.collisionTextAlign = void 0;
      label.collisionOffsetY = 0;
    });
    if (data.length <= 1) {
      return;
    }
    const leftLabels = data.filter((d) => d.midCos < 0).sort((a, b) => a.midSin - b.midSin);
    const rightLabels = data.filter((d) => d.midCos >= 0).sort((a, b) => a.midSin - b.midSin);
    const topLabels = data.filter((d) => {
      var _a;
      return d.midSin < 0 && ((_a = d.calloutLabel) == null ? void 0 : _a.textAlign) === "center";
    }).sort((a, b) => a.midCos - b.midCos);
    const bottomLabels = data.filter((d) => {
      var _a;
      return d.midSin >= 0 && ((_a = d.calloutLabel) == null ? void 0 : _a.textAlign) === "center";
    }).sort((a, b) => a.midCos - b.midCos);
    const tempTextNode = new Text();
    const getTextBBox = (datum) => {
      var _a;
      const label = datum.calloutLabel;
      if (label == null)
        return new BBox(0, 0, 0, 0);
      const labelRadius = datum.outerRadius + calloutLine.length + offset4;
      const x = datum.midCos * labelRadius;
      const y = datum.midSin * labelRadius + label.collisionOffsetY;
      tempTextNode.text = label.text;
      tempTextNode.x = x;
      tempTextNode.y = y;
      tempTextNode.setFont(this.properties.calloutLabel);
      tempTextNode.setAlign({
        textAlign: (_a = label.collisionTextAlign) != null ? _a : label.textAlign,
        textBaseline: label.textBaseline
      });
      return tempTextNode.computeBBox();
    };
    const avoidNeighbourYCollision = (label, next, direction) => {
      const box = getTextBBox(label).grow(minSpacing / 2);
      const other = getTextBBox(next).grow(minSpacing / 2);
      const collidesOrBehind = box.x < other.x + other.width && box.x + box.width > other.x && (direction === "to-top" ? box.y < other.y + other.height : box.y + box.height > other.y);
      if (collidesOrBehind) {
        const dy = direction === "to-top" ? box.y - other.y - other.height : box.y + box.height - other.y;
        next.calloutLabel.collisionOffsetY = dy;
      }
    };
    const avoidYCollisions = (labels) => {
      const midLabel = labels.slice().sort((a, b) => Math.abs(a.midSin) - Math.abs(b.midSin))[0];
      const midIndex = labels.indexOf(midLabel);
      for (let i = midIndex - 1; i >= 0; i--) {
        const prev = labels[i + 1];
        const next = labels[i];
        avoidNeighbourYCollision(prev, next, "to-top");
      }
      for (let i = midIndex + 1; i < labels.length; i++) {
        const prev = labels[i - 1];
        const next = labels[i];
        avoidNeighbourYCollision(prev, next, "to-bottom");
      }
    };
    const avoidXCollisions = (labels) => {
      const labelsCollideLabelsByY = data.some((datum) => datum.calloutLabel.collisionOffsetY !== 0);
      const boxes = labels.map((label) => getTextBBox(label));
      const paddedBoxes = boxes.map((box) => box.clone().grow(minSpacing / 2));
      let labelsCollideLabelsByX = false;
      for (let i = 0; i < paddedBoxes.length && !labelsCollideLabelsByX; i++) {
        const box = paddedBoxes[i];
        for (let j = i + 1; j < labels.length; j++) {
          const other = paddedBoxes[j];
          if (box.collidesBBox(other)) {
            labelsCollideLabelsByX = true;
            break;
          }
        }
      }
      const sectors = fullData.map((datum) => {
        const { startAngle, endAngle, outerRadius } = datum;
        return { startAngle, endAngle, innerRadius, outerRadius };
      });
      const labelsCollideSectors = boxes.some((box) => {
        return sectors.some((sector) => boxCollidesSector(box, sector));
      });
      if (!labelsCollideLabelsByX && !labelsCollideLabelsByY && !labelsCollideSectors) {
        return;
      }
      labels.filter((d) => d.calloutLabel.textAlign === "center").forEach((d) => {
        const label = d.calloutLabel;
        if (d.midCos < 0) {
          label.collisionTextAlign = "right";
        } else if (d.midCos > 0) {
          label.collisionTextAlign = "left";
        } else {
          label.collisionTextAlign = "center";
        }
      });
    };
    avoidYCollisions(leftLabels);
    avoidYCollisions(rightLabels);
    avoidXCollisions(topLabels);
    avoidXCollisions(bottomLabels);
  }
  updateCalloutLabelNodes(seriesRect) {
    const { radiusScale } = this;
    const { calloutLabel, calloutLine } = this.properties;
    const calloutLength = calloutLine.length;
    const { offset: offset4, color } = calloutLabel;
    const tempTextNode = new Text();
    this.calloutLabelSelection.selectByTag(
      2
      /* Label */
    ).forEach((text) => {
      var _a;
      const { datum } = text;
      const label = datum.calloutLabel;
      const radius = radiusScale.convert(datum.radius);
      const outerRadius = Math.max(0, radius);
      if (!(label == null ? void 0 : label.text) || outerRadius === 0 || label.hidden) {
        text.visible = false;
        return;
      }
      const labelRadius = outerRadius + calloutLength + offset4;
      const x = datum.midCos * labelRadius;
      const y = datum.midSin * labelRadius + label.collisionOffsetY;
      const align = {
        textAlign: (_a = label.collisionTextAlign) != null ? _a : label.textAlign,
        textBaseline: label.textBaseline
      };
      tempTextNode.text = label.text;
      tempTextNode.x = x;
      tempTextNode.y = y;
      tempTextNode.setFont(this.properties.calloutLabel);
      tempTextNode.setAlign(align);
      const box = tempTextNode.computeBBox();
      let displayText = label.text;
      let visible = true;
      if (calloutLabel.avoidCollisions) {
        const { textLength, hasVerticalOverflow } = this.getLabelOverflow(label.text, box, seriesRect);
        displayText = label.text.length === textLength ? label.text : `${label.text.substring(0, textLength)}\u2026`;
        visible = !hasVerticalOverflow;
      }
      text.text = displayText;
      text.x = x;
      text.y = y;
      text.setFont(this.properties.calloutLabel);
      text.setAlign(align);
      text.fill = color;
      text.visible = visible;
    });
  }
  computeLabelsBBox(options, seriesRect) {
    return __async(this, null, function* () {
      const { calloutLabel, calloutLine } = this.properties;
      const calloutLength = calloutLine.length;
      const { offset: offset4, maxCollisionOffset, minSpacing } = calloutLabel;
      if (!calloutLabel.avoidCollisions) {
        return null;
      }
      yield this.maybeRefreshNodeData();
      this.updateRadiusScale(false);
      this.computeCalloutLabelCollisionOffsets();
      const textBoxes = [];
      const text = new Text();
      let titleBox;
      const { title } = this.properties;
      if ((title == null ? void 0 : title.text) && title.enabled) {
        const dy = this.getTitleTranslationY();
        if (isFinite(dy)) {
          text.text = title.text;
          text.x = 0;
          text.y = dy;
          text.setFont(title);
          text.setAlign({
            textBaseline: "bottom",
            textAlign: "center"
          });
          titleBox = text.computeBBox();
          textBoxes.push(titleBox);
        }
      }
      this.nodeData.forEach((datum) => {
        var _a;
        const label = datum.calloutLabel;
        if (!label || datum.outerRadius === 0) {
          return null;
        }
        const labelRadius = datum.outerRadius + calloutLength + offset4;
        const x = datum.midCos * labelRadius;
        const y = datum.midSin * labelRadius + label.collisionOffsetY;
        text.text = label.text;
        text.x = x;
        text.y = y;
        text.setFont(this.properties.calloutLabel);
        text.setAlign({
          textAlign: (_a = label.collisionTextAlign) != null ? _a : label.textAlign,
          textBaseline: label.textBaseline
        });
        const box = text.computeBBox();
        label.box = box;
        if (Math.abs(label.collisionOffsetY) > maxCollisionOffset) {
          label.hidden = true;
          return;
        }
        if (titleBox) {
          const seriesTop = seriesRect.y - this.centerY;
          const titleCleanArea = new BBox(
            titleBox.x - minSpacing,
            seriesTop,
            titleBox.width + 2 * minSpacing,
            titleBox.y + titleBox.height + minSpacing - seriesTop
          );
          if (box.collidesBBox(titleCleanArea)) {
            label.hidden = true;
            return;
          }
        }
        if (options.hideWhenNecessary) {
          const { textLength, hasVerticalOverflow, hasSurroundingSeriesOverflow } = this.getLabelOverflow(
            label.text,
            box,
            seriesRect
          );
          const isTooShort = label.text.length > 2 && textLength < 2;
          if (hasVerticalOverflow || isTooShort || hasSurroundingSeriesOverflow) {
            label.hidden = true;
            return;
          }
        }
        label.hidden = false;
        textBoxes.push(box);
      });
      if (textBoxes.length === 0) {
        return null;
      }
      return BBox.merge(textBoxes);
    });
  }
  updateSectorLabelNodes() {
    const { radiusScale } = this;
    const innerRadius = radiusScale.convert(0);
    const { fontSize, fontStyle, fontWeight, fontFamily, positionOffset, positionRatio, color } = this.properties.sectorLabel;
    const isDoughnut = innerRadius > 0;
    const singleVisibleSector = this.seriesItemEnabled.filter(Boolean).length === 1;
    this.sectorLabelSelection.each((text, datum) => {
      const { sectorLabel, outerRadius } = datum;
      let isTextVisible = false;
      if (sectorLabel && outerRadius !== 0) {
        const labelRadius = innerRadius * (1 - positionRatio) + outerRadius * positionRatio + positionOffset;
        text.fill = color;
        text.fontStyle = fontStyle;
        text.fontWeight = fontWeight;
        text.fontSize = fontSize;
        text.fontFamily = fontFamily;
        text.text = sectorLabel.text;
        const shouldPutTextInCenter = !isDoughnut && singleVisibleSector;
        if (shouldPutTextInCenter) {
          text.x = 0;
          text.y = 0;
        } else {
          text.x = datum.midCos * labelRadius;
          text.y = datum.midSin * labelRadius;
        }
        text.textAlign = "center";
        text.textBaseline = "middle";
        const bbox = text.computeBBox();
        const corners = [
          [bbox.x, bbox.y],
          [bbox.x + bbox.width, bbox.y],
          [bbox.x + bbox.width, bbox.y + bbox.height],
          [bbox.x, bbox.y + bbox.height]
        ];
        const { startAngle, endAngle } = datum;
        const sectorBounds = { startAngle, endAngle, innerRadius, outerRadius };
        if (corners.every(([x, y]) => isPointInSector(x, y, sectorBounds))) {
          isTextVisible = true;
        }
      }
      text.visible = isTextVisible;
    });
  }
  updateInnerLabelNodes() {
    const textBBoxes = [];
    const margins = [];
    this.innerLabelsSelection.each((text, datum) => {
      const { fontStyle, fontWeight, fontSize, fontFamily, color } = datum;
      text.fontStyle = fontStyle;
      text.fontWeight = fontWeight;
      text.fontSize = fontSize;
      text.fontFamily = fontFamily;
      text.text = datum.text;
      text.x = 0;
      text.y = 0;
      text.fill = color;
      text.textAlign = "center";
      text.textBaseline = "alphabetic";
      textBBoxes.push(text.computeBBox());
      margins.push(datum.margin);
    });
    const getMarginTop = (index) => index === 0 ? 0 : margins[index];
    const getMarginBottom = (index) => index === margins.length - 1 ? 0 : margins[index];
    const totalHeight = textBBoxes.reduce((sum2, bbox, i) => {
      return sum2 + bbox.height + getMarginTop(i) + getMarginBottom(i);
    }, 0);
    const totalWidth = Math.max(...textBBoxes.map((bbox) => bbox.width));
    const innerRadius = this.getInnerRadius();
    const labelRadius = Math.sqrt(Math.pow(totalWidth / 2, 2) + Math.pow(totalHeight / 2, 2));
    const labelsVisible = labelRadius <= (innerRadius > 0 ? innerRadius : this.getOuterRadius());
    const textBottoms = [];
    for (let i = 0, prev = -totalHeight / 2; i < textBBoxes.length; i++) {
      const bbox = textBBoxes[i];
      const bottom = bbox.height + prev + getMarginTop(i);
      textBottoms.push(bottom);
      prev = bottom + getMarginBottom(i);
    }
    this.innerLabelsSelection.each((text, _datum, index) => {
      text.y = textBottoms[index];
      text.visible = labelsVisible;
    });
  }
  updateZerosumRings() {
    this.zerosumOuterRing.size = this.getOuterRadius() * 2;
    this.zerosumInnerRing.size = this.getInnerRadius() * 2;
  }
  getDatumLegendName(nodeDatum) {
    const { angleKey, calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties;
    const { sectorLabel, calloutLabel, legendItem } = nodeDatum;
    if (legendItemKey && legendItem !== void 0) {
      return legendItem.text;
    } else if (calloutLabelKey && calloutLabelKey !== angleKey && (calloutLabel == null ? void 0 : calloutLabel.text) !== void 0) {
      return calloutLabel.text;
    } else if (sectorLabelKey && sectorLabelKey !== angleKey && (sectorLabel == null ? void 0 : sectorLabel.text) !== void 0) {
      return sectorLabel.text;
    }
  }
  getTooltipHtml(nodeDatum) {
    var _a;
    if (!this.properties.isValid()) {
      return "";
    }
    const {
      datum,
      angleValue,
      sectorFormat: { fill: color }
    } = nodeDatum;
    const title = sanitizeHtml((_a = this.properties.title) == null ? void 0 : _a.text);
    const content = isNumber2(angleValue) ? toFixed(angleValue) : String(angleValue);
    const labelText = this.getDatumLegendName(nodeDatum);
    return this.properties.tooltip.toTooltipHtml(
      {
        title: title != null ? title : labelText,
        content: title && labelText ? `${labelText}: ${content}` : content,
        backgroundColor: color
      },
      {
        datum,
        title,
        color,
        seriesId: this.id,
        angleKey: this.properties.angleKey,
        angleName: this.properties.angleName,
        radiusKey: this.properties.radiusKey,
        radiusName: this.properties.radiusName,
        calloutLabelKey: this.properties.calloutLabelKey,
        calloutLabelName: this.properties.calloutLabelName,
        sectorLabelKey: this.properties.sectorLabelKey,
        sectorLabelName: this.properties.sectorLabelName
      }
    );
  }
  getLegendData(legendType) {
    var _a, _b, _c, _d, _e;
    const { processedData, dataModel } = this;
    if (!dataModel || !(processedData == null ? void 0 : processedData.data.length) || legendType !== "category") {
      return [];
    }
    const { angleKey, calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties;
    if (!legendItemKey && (!calloutLabelKey || calloutLabelKey === angleKey) && (!sectorLabelKey || sectorLabelKey === angleKey))
      return [];
    const { calloutLabelIdx, sectorLabelIdx, legendItemIdx } = this.getProcessedDataIndexes(dataModel);
    const titleText = ((_a = this.properties.title) == null ? void 0 : _a.showInLegend) && this.properties.title.text;
    const legendData = [];
    for (let index = 0; index < processedData.data.length; index++) {
      const { datum, values } = processedData.data[index];
      const labelParts = [];
      if (titleText) {
        labelParts.push(titleText);
      }
      const labels = this.getLabels(
        datum,
        2 * Math.PI,
        2 * Math.PI,
        false,
        values[calloutLabelIdx],
        values[sectorLabelIdx],
        values[legendItemIdx]
      );
      if (legendItemKey && labels.legendItem !== void 0) {
        labelParts.push(labels.legendItem.text);
      } else if (calloutLabelKey && calloutLabelKey !== angleKey && ((_b = labels.calloutLabel) == null ? void 0 : _b.text) !== void 0) {
        labelParts.push((_c = labels.calloutLabel) == null ? void 0 : _c.text);
      } else if (sectorLabelKey && sectorLabelKey !== angleKey && ((_d = labels.sectorLabel) == null ? void 0 : _d.text) !== void 0) {
        labelParts.push((_e = labels.sectorLabel) == null ? void 0 : _e.text);
      }
      if (labelParts.length === 0)
        continue;
      const sectorFormat = this.getSectorFormat(datum, index, false);
      legendData.push({
        legendType: "category",
        id: this.id,
        itemId: index,
        seriesId: this.id,
        enabled: this.seriesItemEnabled[index],
        label: {
          text: labelParts.join(" - ")
        },
        marker: {
          fill: sectorFormat.fill,
          stroke: sectorFormat.stroke,
          fillOpacity: this.properties.fillOpacity,
          strokeOpacity: this.properties.strokeOpacity,
          strokeWidth: this.properties.strokeWidth
        }
      });
    }
    return legendData;
  }
  onLegendItemClick(event) {
    const { enabled, itemId, series } = event;
    if (series.id === this.id) {
      this.toggleSeriesItem(itemId, enabled);
    } else if (series.type === "pie") {
      this.toggleOtherSeriesItems(series, itemId, enabled);
    }
  }
  toggleSeriesItem(itemId, enabled) {
    this.seriesItemEnabled[itemId] = enabled;
    this.nodeDataRefresh = true;
  }
  toggleOtherSeriesItems(series, itemId, enabled) {
    var _a, _b;
    if (!this.properties.legendItemKey || !this.dataModel) {
      return;
    }
    const datumToggledLegendItemValue = series.properties.legendItemKey && ((_a = series.data) == null ? void 0 : _a.find((_, index) => index === itemId)[series.properties.legendItemKey]);
    if (!datumToggledLegendItemValue) {
      return;
    }
    const legendItemIdx = this.dataModel.resolveProcessedDataIndexById(this, `legendItemValue`).index;
    (_b = this.processedData) == null ? void 0 : _b.data.forEach(({ values }, datumItemId) => {
      if (values[legendItemIdx] === datumToggledLegendItemValue) {
        this.toggleSeriesItem(datumItemId, enabled);
      }
    });
  }
  animateEmptyUpdateReady(_data) {
    const { animationManager } = this.ctx;
    const fns = preparePieSeriesAnimationFunctions(
      true,
      this.properties.rotation,
      this.radiusScale,
      this.previousRadiusScale
    );
    fromToMotion(this.id, "nodes", animationManager, [this.itemSelection, this.highlightSelection], fns.nodes);
    fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle);
    seriesLabelFadeInAnimation(this, "callout", animationManager, [this.calloutLabelSelection]);
    seriesLabelFadeInAnimation(this, "sector", animationManager, [this.sectorLabelSelection]);
    seriesLabelFadeInAnimation(this, "inner", animationManager, [this.innerLabelsSelection]);
    this.previousRadiusScale.range = this.radiusScale.range;
  }
  animateWaitingUpdateReady() {
    var _a, _b, _c, _d, _e, _f;
    const { itemSelection, highlightSelection, processedData, radiusScale, previousRadiusScale } = this;
    const { animationManager } = this.ctx;
    const diff2 = (_a = processedData == null ? void 0 : processedData.reduced) == null ? void 0 : _a.diff;
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    const supportedDiff = ((_b = diff2 == null ? void 0 : diff2.moved.length) != null ? _b : 0) === 0 && (diff2 == null ? void 0 : diff2.addedIndices.every((i) => !diff2.removedIndices.includes(i)));
    const hasKeys = ((_c = processedData == null ? void 0 : processedData.defs.keys.length) != null ? _c : 0) > 0;
    const hasUniqueKeys = (_f = (_e = (_d = processedData == null ? void 0 : processedData.reduced) == null ? void 0 : _d.animationValidation) == null ? void 0 : _e.uniqueKeys) != null ? _f : true;
    if (!supportedDiff || !hasKeys || !hasUniqueKeys) {
      this.ctx.animationManager.skipCurrentBatch();
    }
    const fns = preparePieSeriesAnimationFunctions(
      false,
      this.properties.rotation,
      radiusScale,
      previousRadiusScale
    );
    fromToMotion(
      this.id,
      "nodes",
      animationManager,
      [itemSelection, highlightSelection],
      fns.nodes,
      (_, datum) => this.getDatumId(datum),
      diff2
    );
    fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle);
    seriesLabelFadeInAnimation(this, "callout", this.ctx.animationManager, [this.calloutLabelSelection]);
    seriesLabelFadeInAnimation(this, "sector", this.ctx.animationManager, [this.sectorLabelSelection]);
    seriesLabelFadeInAnimation(this, "inner", this.ctx.animationManager, [this.innerLabelsSelection]);
    this.previousRadiusScale.range = this.radiusScale.range;
  }
  animateClearingUpdateEmpty() {
    const { itemSelection, highlightSelection, radiusScale, previousRadiusScale } = this;
    const { animationManager } = this.ctx;
    const fns = preparePieSeriesAnimationFunctions(
      false,
      this.properties.rotation,
      radiusScale,
      previousRadiusScale
    );
    fromToMotion(this.id, "nodes", animationManager, [itemSelection, highlightSelection], fns.nodes);
    fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle);
    seriesLabelFadeOutAnimation(this, "callout", this.ctx.animationManager, [this.calloutLabelSelection]);
    seriesLabelFadeOutAnimation(this, "sector", this.ctx.animationManager, [this.sectorLabelSelection]);
    seriesLabelFadeOutAnimation(this, "inner", this.ctx.animationManager, [this.innerLabelsSelection]);
    this.previousRadiusScale.range = this.radiusScale.range;
  }
  getDatumIdFromData(datum) {
    var _a, _b, _c;
    const { calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties;
    if (!((_c = (_b = (_a = this.processedData) == null ? void 0 : _a.reduced) == null ? void 0 : _b.animationValidation) == null ? void 0 : _c.uniqueKeys)) {
      return;
    }
    if (legendItemKey) {
      return datum[legendItemKey];
    } else if (calloutLabelKey) {
      return datum[calloutLabelKey];
    } else if (sectorLabelKey) {
      return datum[sectorLabelKey];
    }
  }
  getDatumId(datum) {
    var _a;
    const { index } = datum;
    return (_a = this.getDatumIdFromData(datum.datum)) != null ? _a : `${index}`;
  }
  onDataChange() {
    this.processSeriesItemEnabled();
  }
};
PieSeries.className = "PieSeries";
PieSeries.type = "pie";
var PieSeriesModule = {
  type: "series",
  optionsKey: "series[]",
  packageType: "community",
  chartTypes: ["polar"],
  identifier: "pie",
  instanceConstructor: PieSeries,
  seriesDefaults: {},
  themeTemplate: {
    __extends__: EXTENDS_SERIES_DEFAULTS,
    title: {
      enabled: true,
      fontStyle: void 0,
      fontWeight: FONT_WEIGHT2.NORMAL,
      fontSize: 14,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_MUTED_LABEL_COLOUR,
      spacing: 5
    },
    calloutLabel: {
      enabled: true,
      fontStyle: void 0,
      fontWeight: void 0,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_LABEL_COLOUR,
      offset: 3,
      minAngle: 0
    },
    sectorLabel: {
      enabled: true,
      fontStyle: void 0,
      fontWeight: FONT_WEIGHT2.NORMAL,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_INSIDE_SERIES_LABEL_COLOUR,
      positionOffset: 0,
      positionRatio: 0.5
    },
    calloutLine: {
      length: 10,
      strokeWidth: 2
    },
    fillOpacity: 1,
    strokeOpacity: 1,
    strokeWidth: 1,
    lineDash: [0],
    lineDashOffset: 0,
    rotation: 0,
    outerRadiusOffset: 0,
    innerRadiusOffset: 0,
    // @todo(AG-10275) Uncomment this
    // sectorSpacing: 1,
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    },
    innerLabels: {
      fontStyle: void 0,
      fontWeight: void 0,
      fontSize: 12,
      fontFamily: DEFAULT_FONT_FAMILY,
      color: DEFAULT_LABEL_COLOUR,
      margin: 2
    },
    // @todo(AG-10275) Remove this
    // @ts-expect-error
    __BACKGROUND_COLOR_DO_NOT_USE: DEFAULT_BACKGROUND_COLOUR
  },
  paletteFactory: ({ takeColors, colorsCount, userPalette }) => {
    const { fills, strokes } = takeColors(colorsCount);
    return {
      fills,
      strokes: userPalette ? strokes : [],
      calloutLine: {
        colors: strokes
      }
    };
  }
};
function registerInbuiltModules() {
  registerModule(BackgroundModule);
  registerModule(NavigatorModule);
  registerModule(AreaSeriesModule);
  registerModule(BarSeriesModule);
  registerModule(BubbleSeriesModule);
  registerModule(LineSeriesModule);
  registerModule(ScatterSeriesModule);
  registerModule(PieSeriesModule);
  registerModule(HistogramSeriesModule);
}
var module_support_exports = {};
__export(module_support_exports, {
  ADD_PHASE: () => ADD_PHASE,
  AGG_VALUES_EXTENT: () => AGG_VALUES_EXTENT,
  AND: () => AND,
  ARRAY: () => ARRAY,
  ARRAY_OF: () => ARRAY_OF,
  AbstractBarSeries: () => AbstractBarSeries,
  AbstractBarSeriesProperties: () => AbstractBarSeriesProperties,
  ActionOnSet: () => ActionOnSet,
  Animation: () => Animation,
  AnimationManager: () => AnimationManager,
  AreaSeriesTag: () => AreaSeriesTag,
  Axis: () => Axis,
  AxisLabel: () => AxisLabel,
  AxisTick: () => AxisTick,
  BOOLEAN: () => BOOLEAN,
  BOOLEAN_ARRAY: () => BOOLEAN_ARRAY,
  Background: () => Background,
  BackgroundModule: () => BackgroundModule,
  BaseModuleInstance: () => BaseModuleInstance,
  BaseProperties: () => BaseProperties,
  COLOR_STRING: () => COLOR_STRING,
  COLOR_STRING_ARRAY: () => COLOR_STRING_ARRAY,
  CartesianAxis: () => CartesianAxis,
  CartesianSeries: () => CartesianSeries,
  CartesianSeriesNodeClickEvent: () => CartesianSeriesNodeClickEvent,
  CartesianSeriesProperties: () => CartesianSeriesProperties,
  CategoryAxis: () => CategoryAxis,
  ChartAxisDirection: () => ChartAxisDirection,
  ChartEventManager: () => ChartEventManager,
  ChartUpdateType: () => ChartUpdateType,
  CursorManager: () => CursorManager,
  DATE: () => DATE,
  DATE_ARRAY: () => DATE_ARRAY,
  DATE_OR_DATETIME_MS: () => DATE_OR_DATETIME_MS,
  DEGREE: () => DEGREE,
  DIRECTION: () => DIRECTION,
  DataController: () => DataController,
  DataModel: () => DataModel,
  Default: () => Default,
  Deprecated: () => Deprecated,
  DeprecatedAndRenamedTo: () => DeprecatedAndRenamedTo,
  FONT_STYLE: () => FONT_STYLE,
  FONT_WEIGHT: () => FONT_WEIGHT,
  FROM_TO_MIXINS: () => FROM_TO_MIXINS,
  FUNCTION: () => FUNCTION,
  GREATER_THAN: () => GREATER_THAN,
  HierarchyNode: () => HierarchyNode,
  HierarchySeries: () => HierarchySeries,
  HierarchySeriesProperties: () => HierarchySeriesProperties,
  HighlightManager: () => HighlightManager,
  HighlightStyle: () => HighlightStyle,
  INITIAL_LOAD: () => INITIAL_LOAD,
  INTERACTION_RANGE: () => INTERACTION_RANGE,
  InteractionManager: () => InteractionManager,
  LABEL_PHASE: () => LABEL_PHASE,
  LESS_THAN: () => LESS_THAN,
  LINE_CAP: () => LINE_CAP,
  LINE_DASH: () => LINE_DASH,
  LINE_JOIN: () => LINE_JOIN,
  Layers: () => Layers,
  LayoutService: () => LayoutService,
  MATCHING_CROSSLINE_TYPE: () => MATCHING_CROSSLINE_TYPE,
  MAX_SPACING: () => MAX_SPACING,
  MIN_SPACING: () => MIN_SPACING,
  MODULE_CONFLICTS: () => MODULE_CONFLICTS,
  Motion: () => easing_exports,
  NAN: () => NAN,
  NODE_UPDATE_PHASES: () => NODE_UPDATE_PHASES,
  NUMBER: () => NUMBER,
  NUMBER_ARRAY: () => NUMBER_ARRAY,
  NUMBER_OR_NAN: () => NUMBER_OR_NAN,
  OBJECT: () => OBJECT,
  OBJECT_ARRAY: () => OBJECT_ARRAY,
  OR: () => OR,
  OVERFLOW_STRATEGY: () => OVERFLOW_STRATEGY,
  PLACEMENT: () => PLACEMENT,
  POLAR_AXIS_SHAPE: () => POLAR_AXIS_SHAPE,
  POSITION: () => POSITION,
  POSITIVE_NUMBER: () => POSITIVE_NUMBER,
  PolarAxis: () => PolarAxis,
  PolarSeries: () => PolarSeries,
  PropertiesArray: () => PropertiesArray,
  ProxyOnWrite: () => ProxyOnWrite,
  ProxyProperty: () => ProxyProperty,
  ProxyPropertyOnWrite: () => ProxyPropertyOnWrite,
  QUICK_TRANSITION: () => QUICK_TRANSITION,
  RATIO: () => RATIO,
  REGISTERED_MODULES: () => REGISTERED_MODULES,
  REMOVE_PHASE: () => REMOVE_PHASE,
  RepeatType: () => RepeatType,
  SMALLEST_KEY_INTERVAL: () => SMALLEST_KEY_INTERVAL,
  SORT_DOMAIN_GROUPS: () => SORT_DOMAIN_GROUPS,
  STRING: () => STRING,
  STRING_ARRAY: () => STRING_ARRAY,
  Series: () => Series,
  SeriesItemHighlightStyle: () => SeriesItemHighlightStyle,
  SeriesMarker: () => SeriesMarker,
  SeriesNodeClickEvent: () => SeriesNodeClickEvent,
  SeriesNodePickMode: () => SeriesNodePickMode,
  SeriesProperties: () => SeriesProperties,
  SeriesTooltip: () => SeriesTooltip,
  StateMachine: () => StateMachine,
  TEXT_ALIGN: () => TEXT_ALIGN,
  TEXT_WRAP: () => TEXT_WRAP,
  Tags: () => Tags,
  TooltipManager: () => TooltipManager,
  UNION: () => UNION,
  UPDATE_PHASE: () => UPDATE_PHASE,
  UpdateService: () => UpdateService,
  VERTICAL_ALIGN: () => VERTICAL_ALIGN,
  Validate: () => Validate,
  ZoomManager: () => ZoomManager,
  __FORCE_MODULE_DETECTION: () => __FORCE_MODULE_DETECTION2,
  accumulateGroup: () => accumulateGroup,
  accumulatedValue: () => accumulatedValue,
  accumulativeValueProperty: () => accumulativeValueProperty,
  adjustLabelPlacement: () => adjustLabelPlacement,
  animationValidation: () => animationValidation,
  area: () => area,
  arraysEqual: () => arraysEqual,
  assignJsonApplyConstructedArray: () => assignJsonApplyConstructedArray,
  average: () => average,
  backfillPathPointData: () => backfillPathPointData,
  buildResetPathFn: () => buildResetPathFn,
  checkCrisp: () => checkCrisp,
  clamp: () => clamp2,
  clampArray: () => clampArray,
  collapsedStartingBarPosition: () => collapsedStartingBarPosition,
  count: () => count,
  countFractionDigits: () => countFractionDigits,
  createDatumId: () => createDatumId,
  createDeprecationWarning: () => createDeprecationWarning,
  deconstructSelectionsOrNodes: () => deconstructSelectionsOrNodes,
  deepMerge: () => deepMerge,
  determinePathStatus: () => determinePathStatus,
  diff: () => diff,
  enterpriseModule: () => enterpriseModule,
  extent: () => extent,
  extractDecoratedProperties: () => extractDecoratedProperties,
  fixNumericExtent: () => fixNumericExtent,
  fromToMotion: () => fromToMotion,
  getRectConfig: () => getRectConfig,
  groupAccumulativeValueProperty: () => groupAccumulativeValueProperty,
  groupAverage: () => groupAverage,
  groupCount: () => groupCount,
  groupSum: () => groupSum,
  hasRegisteredEnterpriseModules: () => hasRegisteredEnterpriseModules,
  injectStyle: () => injectStyle,
  invertShapeDirection: () => invertShapeDirection,
  isArray: () => isArray,
  isBoolean: () => isBoolean,
  isDate: () => isDate,
  isDecoratedObject: () => isDecoratedObject,
  isDefined: () => isDefined,
  isEqual: () => isEqual,
  isFiniteNumber: () => isFiniteNumber,
  isFunction: () => isFunction,
  isHtmlElement: () => isHtmlElement,
  isNegative: () => isNegative,
  isNumber: () => isNumber,
  isObject: () => isObject,
  isObjectLike: () => isObjectLike,
  isPlainObject: () => isPlainObject,
  isProperties: () => isProperties,
  isReal: () => isReal,
  isString: () => isString,
  isValidDate: () => isValidDate,
  keyProperty: () => keyProperty,
  listDecoratedProperties: () => listDecoratedProperties,
  markerFadeInAnimation: () => markerFadeInAnimation,
  markerPaletteFactory: () => markerPaletteFactory,
  markerScaleInAnimation: () => markerScaleInAnimation,
  markerSwipeScaleInAnimation: () => markerSwipeScaleInAnimation,
  mergeDefaults: () => mergeDefaults,
  midpointStartingBarPosition: () => midpointStartingBarPosition,
  minMax: () => minMax,
  mod: () => mod,
  normaliseGroupTo: () => normaliseGroupTo,
  normalisePropertyTo: () => normalisePropertyTo,
  normalisedExtent: () => normalisedExtent,
  normalisedExtentWithMetadata: () => normalisedExtentWithMetadata,
  pairCategoryData: () => pairCategoryData,
  pairContinuousData: () => pairContinuousData,
  partialAssign: () => partialAssign,
  pathFadeInAnimation: () => pathFadeInAnimation,
  pathFadeOutAnimation: () => pathFadeOutAnimation,
  pathSwipeInAnimation: () => pathSwipeInAnimation,
  predicateWithMessage: () => predicateWithMessage,
  prepareAreaPathAnimation: () => prepareAreaPathAnimation,
  prepareAxisAnimationContext: () => prepareAxisAnimationContext,
  prepareAxisAnimationFunctions: () => prepareAxisAnimationFunctions,
  prepareBarAnimationFunctions: () => prepareBarAnimationFunctions,
  prepareLinePathAnimation: () => prepareLinePathAnimation,
  prepareLinePathAnimationFns: () => prepareLinePathAnimationFns,
  prepareMarkerAnimation: () => prepareMarkerAnimation,
  range: () => range2,
  rangedValueProperty: () => rangedValueProperty,
  registerModule: () => registerModule,
  registerModuleConflicts: () => registerModuleConflicts,
  renderPartialPath: () => renderPartialPath,
  resetAxisGroupFn: () => resetAxisGroupFn,
  resetAxisLabelSelectionFn: () => resetAxisLabelSelectionFn,
  resetAxisLineSelectionFn: () => resetAxisLineSelectionFn,
  resetAxisSelectionFn: () => resetAxisSelectionFn,
  resetBarSelectionsFn: () => resetBarSelectionsFn,
  resetIds: () => resetIds,
  resetLabelFn: () => resetLabelFn,
  resetMarkerFn: () => resetMarkerFn,
  resetMarkerPositionFn: () => resetMarkerPositionFn,
  resetMotion: () => resetMotion,
  round: () => round,
  seriesLabelFadeInAnimation: () => seriesLabelFadeInAnimation,
  seriesLabelFadeOutAnimation: () => seriesLabelFadeOutAnimation,
  singleSeriesPaletteFactory: () => singleSeriesPaletteFactory,
  staticFromToMotion: () => staticFromToMotion,
  stringify: () => stringify,
  sum: () => sum,
  toArray: () => toArray,
  toFixed: () => toFixed,
  toReal: () => toReal,
  trailingAccumulatedValue: () => trailingAccumulatedValue,
  trailingAccumulatedValueProperty: () => trailingAccumulatedValueProperty,
  trailingValue: () => trailingValue,
  trailingValueProperty: () => trailingValueProperty,
  unique: () => unique,
  updateClipPath: () => updateClipPath,
  updateLabelNode: () => updateLabelNode,
  updateRect: () => updateRect,
  validateCrossLineValues: () => validateCrossLineValues,
  valueProperty: () => valueProperty
});
function invertShapeDirection(...supportedShapes) {
  for (const shape of supportedShapes) {
    if (shape instanceof Rect) {
      const { x, y, width, height } = shape;
      shape.setProperties({ x: y, y: x, width: height, height: width });
    } else if (shape instanceof Line) {
      const { x1, y1, x2, y2 } = shape;
      shape.setProperties({ x1: y1, y1: x1, x2: y2, y2: x2 });
    }
  }
}
var _HierarchyNode = class _HierarchyNode2 {
  constructor(series, index, datum, size, colorValue, fill, stroke, sumSize, depth, parent, children) {
    this.series = series;
    this.index = index;
    this.datum = datum;
    this.size = size;
    this.colorValue = colorValue;
    this.fill = fill;
    this.stroke = stroke;
    this.sumSize = sumSize;
    this.depth = depth;
    this.parent = parent;
    this.children = children;
    this.midPoint = { x: 0, y: 0 };
  }
  contains(other) {
    let current = other;
    while (current != null && current.index >= this.index) {
      if (current === this) {
        return true;
      }
      current = current.parent;
    }
    return false;
  }
  walk(callback, order = _HierarchyNode2.Walk.PreOrder) {
    if (order === _HierarchyNode2.Walk.PreOrder) {
      callback(this);
    }
    this.children.forEach((child) => {
      child.walk(callback, order);
    });
    if (order === _HierarchyNode2.Walk.PostOrder) {
      callback(this);
    }
  }
  *[Symbol.iterator]() {
    yield this;
    for (const child of this.children) {
      yield* __yieldStar(__yieldStar2(child));
    }
  }
};
_HierarchyNode.Walk = {
  PreOrder: 0,
  PostOrder: 1
};
var HierarchyNode = _HierarchyNode;
var HierarchySeries = class extends Series {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [
        0
        /* EXACT_SHAPE_MATCH */
      ],
      contentGroupVirtual: false
    });
    this.rootNode = new HierarchyNode(
      this,
      0,
      void 0,
      0,
      void 0,
      void 0,
      void 0,
      0,
      void 0,
      void 0,
      []
    );
    this.colorDomain = [0, 0];
    this.maxDepth = 0;
    this.animationState = new StateMachine(
      "empty",
      {
        empty: {
          update: {
            target: "ready",
            action: (data) => this.animateEmptyUpdateReady(data)
          }
        },
        ready: {
          updateData: "waiting",
          clear: "clearing",
          highlight: (data) => this.animateReadyHighlight(data),
          resize: (data) => this.animateReadyResize(data)
        },
        waiting: {
          update: {
            target: "ready",
            action: (data) => this.animateWaitingUpdateReady(data)
          }
        },
        clearing: {
          update: {
            target: "empty",
            action: (data) => this.animateClearingUpdateEmpty(data)
          }
        }
      },
      () => this.checkProcessedDataAnimatable()
    );
  }
  hasData() {
    return Array.isArray(this.data) && this.data.length > 0;
  }
  processData() {
    return __async(this, null, function* () {
      var _a, _b;
      const { childrenKey, sizeKey, colorKey, fills, strokes, colorRange } = this.properties;
      let index = 0;
      const getIndex = () => {
        index += 1;
        return index;
      };
      let maxDepth = 0;
      let minColor = Infinity;
      let maxColor = -Infinity;
      const colors = new Array(((_b = (_a = this.data) == null ? void 0 : _a.length) != null ? _b : 0) + 1).fill(void 0);
      const createNode = (datum, parent) => {
        const index2 = getIndex();
        const depth = parent.depth != null ? parent.depth + 1 : 0;
        const children = childrenKey != null ? datum[childrenKey] : void 0;
        const isLeaf = children == null || children.length === 0;
        let size = sizeKey != null ? datum[sizeKey] : void 0;
        if (Number.isFinite(size)) {
          size = Math.max(size, 0);
        } else {
          size = isLeaf ? 1 : 0;
        }
        const sumSize = size;
        maxDepth = Math.max(maxDepth, depth);
        const color = colorKey != null ? datum[colorKey] : void 0;
        if (typeof color === "number") {
          colors[index2] = color;
          minColor = Math.min(minColor, color);
          maxColor = Math.max(maxColor, color);
        }
        return appendChildren(
          new HierarchyNode(
            this,
            index2,
            datum,
            size,
            color,
            void 0,
            void 0,
            sumSize,
            depth,
            parent,
            []
          ),
          children
        );
      };
      const appendChildren = (node, data) => {
        data == null ? void 0 : data.forEach((datum) => {
          const child = createNode(datum, node);
          node.children.push(child);
          node.sumSize += child.sumSize;
        });
        return node;
      };
      const rootNode = appendChildren(
        new HierarchyNode(
          this,
          0,
          void 0,
          0,
          void 0,
          void 0,
          void 0,
          0,
          void 0,
          void 0,
          []
        ),
        this.data
      );
      const colorDomain = [minColor, maxColor];
      let colorScale;
      if (colorRange != null && Number.isFinite(minColor) && Number.isFinite(maxColor)) {
        colorScale = new ColorScale();
        colorScale.domain = colorDomain;
        colorScale.range = colorRange;
        colorScale.update();
      }
      rootNode.children.forEach((child, index2) => {
        child.walk((node) => {
          let fill;
          const color = colors[node.index];
          if (color != null) {
            fill = colorScale == null ? void 0 : colorScale.convert(color);
          }
          fill != null ? fill : fill = fills == null ? void 0 : fills[index2 % fills.length];
          node.fill = fill;
          node.stroke = colorScale == null ? strokes == null ? void 0 : strokes[index2 % strokes.length] : "rgba(0, 0, 0, 0.2)";
        });
      });
      this.rootNode = rootNode;
      this.maxDepth = maxDepth;
      this.colorDomain = colorDomain;
    });
  }
  update(_0) {
    return __async(this, arguments, function* ({ seriesRect }) {
      yield this.updateSelections();
      yield this.updateNodes();
      const animationData = this.getAnimationData();
      const resize = this.checkResize(seriesRect);
      if (resize) {
        this.animationState.transition("resize", animationData);
      }
      this.animationState.transition("update", animationData);
    });
  }
  resetAllAnimation(data) {
    var _a;
    const datum = (_a = this.animationResetFns) == null ? void 0 : _a.datum;
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    if (datum != null) {
      resetMotion(data.datumSelections, datum);
    }
  }
  animateEmptyUpdateReady(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animateWaitingUpdateReady(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animateReadyHighlight(data) {
    var _a;
    const datum = (_a = this.animationResetFns) == null ? void 0 : _a.datum;
    if (datum != null) {
      resetMotion([data], datum);
    }
  }
  animateReadyResize(data) {
    this.resetAllAnimation(data);
  }
  animateClearingUpdateEmpty(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animationTransitionClear() {
    this.animationState.transition("clear", this.getAnimationData());
  }
  getAnimationData() {
    const animationData = {
      datumSelections: [this.groupSelection]
    };
    return animationData;
  }
  isProcessedDataAnimatable() {
    return true;
  }
  checkProcessedDataAnimatable() {
    if (!this.isProcessedDataAnimatable()) {
      this.ctx.animationManager.skipCurrentBatch();
    }
  }
  getLabelData() {
    return [];
  }
  getSeriesDomain() {
    return [NaN, NaN];
  }
  getLegendData(legendType) {
    const { colorKey, colorName, colorRange, visible } = this.properties;
    return legendType === "gradient" && colorKey != null && colorRange != null ? [
      {
        legendType: "gradient",
        enabled: visible,
        seriesId: this.id,
        colorName,
        colorRange,
        colorDomain: this.colorDomain
      }
    ] : [];
  }
  getDatumIdFromData(node) {
    return `${node.index}`;
  }
  getDatumId(node) {
    return this.getDatumIdFromData(node);
  }
};
var HierarchySeriesProperties = class extends SeriesProperties {
  constructor() {
    super(...arguments);
    this.childrenKey = "children";
    this.fills = Object.values(DEFAULT_FILLS);
    this.strokes = Object.values(DEFAULT_STROKES);
  }
};
__decorateClass([
  Validate(STRING)
], HierarchySeriesProperties.prototype, "childrenKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], HierarchySeriesProperties.prototype, "sizeKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], HierarchySeriesProperties.prototype, "colorKey", 2);
__decorateClass([
  Validate(STRING, { optional: true })
], HierarchySeriesProperties.prototype, "colorName", 2);
__decorateClass([
  Validate(COLOR_STRING_ARRAY)
], HierarchySeriesProperties.prototype, "fills", 2);
__decorateClass([
  Validate(COLOR_STRING_ARRAY)
], HierarchySeriesProperties.prototype, "strokes", 2);
__decorateClass([
  Validate(COLOR_STRING_ARRAY, { optional: true })
], HierarchySeriesProperties.prototype, "colorRange", 2);
var POLAR_AXIS_SHAPE = UNION(["polygon", "circle"], "a polar axis shape");
var PolarAxis = class extends Axis {
  constructor() {
    super(...arguments);
    this.shape = "polygon";
    this.innerRadiusRatio = 0;
    this.defaultTickMinSpacing = 20;
  }
  computeLabelsBBox(_options, _seriesRect) {
    return null;
  }
};
__decorateClass([
  Validate(POLAR_AXIS_SHAPE)
], PolarAxis.prototype, "shape", 2);
__decorateClass([
  Validate(RATIO)
], PolarAxis.prototype, "innerRadiusRatio", 2);
var __FORCE_MODULE_DETECTION2 = 0;
var SERIES_FACTORIES = {};
var SERIES_DEFAULTS = {};
var SERIES_THEME_TEMPLATES = {};
var ENTERPRISE_SERIES_THEME_TEMPLATES = {};
var SERIES_PALETTE_FACTORIES = {};
var SOLO_SERIES_TYPES = /* @__PURE__ */ new Set();
var STACKABLE_SERIES_TYPES = /* @__PURE__ */ new Set();
var GROUPABLE_SERIES_TYPES = /* @__PURE__ */ new Set();
var STACKED_BY_DEFAULT_SERIES_TYPES = /* @__PURE__ */ new Set();
var SWAP_DEFAULT_AXES_CONDITIONS = {};
var CUSTOM_DEFAULTS_FUNCTIONS = {};
function registerSeries(seriesType, chartType2, cstr, defaults, theme, enterpriseTheme, paletteFactory, solo, stackable, groupable, stackedByDefault, swapDefaultAxesCondition, customDefaultsFunction) {
  SERIES_FACTORIES[seriesType] = cstr;
  SERIES_DEFAULTS[seriesType] = defaults;
  registerSeriesThemeTemplate(seriesType, theme, enterpriseTheme);
  if (paletteFactory) {
    addSeriesPaletteFactory(seriesType, paletteFactory);
  }
  if (solo) {
    addSoloSeriesType(seriesType);
  }
  if (stackable) {
    addStackableSeriesType(seriesType);
  }
  if (groupable) {
    addGroupableSeriesType(seriesType);
  }
  if (stackedByDefault) {
    addStackedByDefaultSeriesType(seriesType);
  }
  if (swapDefaultAxesCondition) {
    addSwapDefaultAxesCondition(seriesType, swapDefaultAxesCondition);
  }
  if (customDefaultsFunction) {
    addCustomDefaultsFunctions(seriesType, customDefaultsFunction);
  }
  registerChartSeriesType(seriesType, chartType2);
}
function registerSeriesThemeTemplate(seriesType, themeTemplate, enterpriseThemeTemplate = {}) {
  const existingTemplate = SERIES_THEME_TEMPLATES[seriesType];
  SERIES_THEME_TEMPLATES[seriesType] = jsonMerge([existingTemplate, themeTemplate]);
  ENTERPRISE_SERIES_THEME_TEMPLATES[seriesType] = jsonMerge([
    existingTemplate,
    themeTemplate,
    enterpriseThemeTemplate
  ]);
}
function getSeries(chartType2, moduleCtx) {
  const seriesConstructor = SERIES_FACTORIES[chartType2];
  if (seriesConstructor) {
    return new seriesConstructor(moduleCtx);
  }
  throw new Error(`AG Charts - unknown series type: ${chartType2}`);
}
function getSeriesDefaults(chartType2) {
  return SERIES_DEFAULTS[chartType2];
}
function getSeriesThemeTemplate(chartType2) {
  if (hasRegisteredEnterpriseModules()) {
    return ENTERPRISE_SERIES_THEME_TEMPLATES[chartType2];
  }
  return SERIES_THEME_TEMPLATES[chartType2];
}
function addSeriesPaletteFactory(seriesType, factory) {
  SERIES_PALETTE_FACTORIES[seriesType] = factory;
}
function getSeriesPaletteFactory(seriesType) {
  return SERIES_PALETTE_FACTORIES[seriesType];
}
function isSoloSeries(seriesType) {
  return SOLO_SERIES_TYPES.has(seriesType);
}
function isStackableSeries(seriesType) {
  return STACKABLE_SERIES_TYPES.has(seriesType);
}
function isGroupableSeries(seriesType) {
  return GROUPABLE_SERIES_TYPES.has(seriesType);
}
function isSeriesStackedByDefault(seriesType) {
  return STACKED_BY_DEFAULT_SERIES_TYPES.has(seriesType);
}
function addGroupableSeriesType(seriesType) {
  GROUPABLE_SERIES_TYPES.add(seriesType);
}
function addSoloSeriesType(seriesType) {
  SOLO_SERIES_TYPES.add(seriesType);
}
function addStackableSeriesType(seriesType) {
  STACKABLE_SERIES_TYPES.add(seriesType);
}
function addStackedByDefaultSeriesType(seriesType) {
  STACKED_BY_DEFAULT_SERIES_TYPES.add(seriesType);
}
function addSwapDefaultAxesCondition(seriesType, predicate) {
  SWAP_DEFAULT_AXES_CONDITIONS[seriesType] = predicate;
}
function addCustomDefaultsFunctions(seriesType, predicate) {
  CUSTOM_DEFAULTS_FUNCTIONS[seriesType] = predicate;
}
function isDefaultAxisSwapNeeded(opts) {
  var _a, _b;
  let result;
  for (const series of (_a = opts.series) != null ? _a : []) {
    const { type = "line" } = series;
    const isDefaultAxisSwapped = (_b = SWAP_DEFAULT_AXES_CONDITIONS[type]) == null ? void 0 : _b.call(SWAP_DEFAULT_AXES_CONDITIONS, series);
    if (isDefaultAxisSwapped != null) {
      if (result != null && result != isDefaultAxisSwapped) {
        throw new Error("AG Charts - The provided series have incompatible directions");
      }
      result = isDefaultAxisSwapped;
    }
  }
  return result;
}
function executeCustomDefaultsFunctions(opts, initialDefaults) {
  var _a;
  let result = initialDefaults;
  for (const series of (_a = opts.series) != null ? _a : []) {
    const { type } = series;
    const fn = type != null ? CUSTOM_DEFAULTS_FUNCTIONS[type] : void 0;
    if (fn !== void 0) {
      result = __spreadValues(__spreadValues({}, result), fn(series));
    }
  }
  return result;
}
function setupModules() {
  var _a;
  for (const m of REGISTERED_MODULES) {
    if (m.packageType === "enterprise" && !verifyIfModuleExpected(m)) {
      Logger.errorOnce("Unexpected enterprise module registered: " + m.identifier);
    }
    if (JSON_APPLY_PLUGINS.constructors != null && m.optionConstructors != null) {
      Object.assign(JSON_APPLY_PLUGINS.constructors, m.optionConstructors);
    }
    if (m.type === "root" && m.themeTemplate) {
      for (const chartType2 of m.chartTypes) {
        registerChartDefaults(chartType2, m.themeTemplate);
      }
    }
    if (m.type === "root" && ((_a = m.conflicts) == null ? void 0 : _a.length)) {
      registerModuleConflicts(m.optionsKey, m.conflicts);
    }
    if (m.type === "series") {
      if (m.chartTypes.length > 1)
        throw new Error("AG Charts - Module definition error: " + m.identifier);
      registerSeries(
        m.identifier,
        m.chartTypes[0],
        m.instanceConstructor,
        m.seriesDefaults,
        m.themeTemplate,
        m.enterpriseThemeTemplate,
        m.paletteFactory,
        m.solo,
        m.stackable,
        m.groupable,
        m.stackedByDefault,
        m.swapDefaultAxesCondition,
        m.customDefaultsFunction
      );
    }
    if (m.type === "series-option" && m.themeTemplate) {
      for (const seriesType of m.seriesTypes) {
        registerSeriesThemeTemplate(seriesType, m.themeTemplate);
      }
    }
    if (m.type === "axis-option" && m.themeTemplate) {
      for (const axisType of m.axisTypes) {
        const axisTypeTheme = m.themeTemplate[axisType];
        const theme = __spreadValues(__spreadValues({}, m.themeTemplate), typeof axisTypeTheme === "object" ? axisTypeTheme : {});
        for (const axisType2 of m.axisTypes) {
          delete theme[axisType2];
        }
        registerAxisThemeTemplate(axisType, theme);
      }
    }
    if (m.type === "axis") {
      registerAxis(m.identifier, m.instanceConstructor);
      if (m.themeTemplate) {
        registerAxisThemeTemplate(m.identifier, m.themeTemplate);
      }
    }
    if (m.type === "legend") {
      registerLegend(m.identifier, m.optionsKey, m.instanceConstructor, m.themeTemplate);
    }
  }
  if (hasRegisteredEnterpriseModules()) {
    const expectedButUnused = getUnusedExpectedModules();
    if (expectedButUnused.length > 0) {
      Logger.errorOnce("Enterprise modules expected but not registered: ", expectedButUnused);
    }
  }
}
var _HierarchyChart = class _HierarchyChart2 extends Chart {
  constructor(specialOverrides, resources) {
    super(specialOverrides, resources);
    this._data = {};
  }
  performLayout() {
    return __async(this, null, function* () {
      const shrinkRect = yield __superGet(_HierarchyChart2.prototype, this, "performLayout").call(this);
      const {
        seriesArea: { padding },
        seriesRoot
      } = this;
      const fullSeriesRect = shrinkRect.clone();
      shrinkRect.shrink(padding.left, "left");
      shrinkRect.shrink(padding.top, "top");
      shrinkRect.shrink(padding.right, "right");
      shrinkRect.shrink(padding.bottom, "bottom");
      this.seriesRect = shrinkRect;
      this.animationRect = shrinkRect;
      this.hoverRect = shrinkRect;
      seriesRoot.translationX = Math.floor(shrinkRect.x);
      seriesRoot.translationY = Math.floor(shrinkRect.y);
      yield Promise.all(
        this.series.map((series) => __async(this, null, function* () {
          yield series.update({ seriesRect: shrinkRect });
        }))
      );
      seriesRoot.visible = this.series[0].visible;
      seriesRoot.setClipRectInGroupCoordinateSpace(
        new BBox(shrinkRect.x, shrinkRect.y, shrinkRect.width, shrinkRect.height)
      );
      this.layoutService.dispatchLayoutComplete({
        type: "layout-complete",
        chart: { width: this.scene.width, height: this.scene.height },
        clipSeries: false,
        series: { rect: fullSeriesRect, paddedRect: shrinkRect, visible: true },
        axes: []
      });
      return shrinkRect;
    });
  }
};
_HierarchyChart.className = "HierarchyChart";
_HierarchyChart.type = "hierarchy";
var HierarchyChart = _HierarchyChart;
function removeUsedEnterpriseOptions(options) {
  var _a, _b, _c, _d;
  const usedOptions = [];
  const optionsChartType = getChartType(optionsType(options));
  for (const { type, chartTypes, optionsKey, optionsInnerKey, identifier } of EXPECTED_ENTERPRISE_MODULES) {
    if (optionsChartType !== "unknown" && !chartTypes.includes(optionsChartType))
      continue;
    if (type === "root" || type === "legend") {
      const optionValue = options[optionsKey];
      if (optionValue == null)
        continue;
      if (!optionsInnerKey) {
        usedOptions.push(optionsKey);
        delete options[optionsKey];
      } else if (optionValue[optionsInnerKey]) {
        usedOptions.push(`${optionsKey}.${optionsInnerKey}`);
        delete optionValue[optionsInnerKey];
      }
    } else if (type === "axis") {
      if (!("axes" in options) || !((_a = options.axes) == null ? void 0 : _a.some((axis) => axis.type === identifier)))
        continue;
      usedOptions.push(`axis[type=${identifier}]`);
      options.axes = options.axes.filter((axis) => axis.type !== identifier);
    } else if (type === "axis-option") {
      if (!("axes" in options) || !((_b = options.axes) == null ? void 0 : _b.some((axis) => axis[optionsKey])))
        continue;
      usedOptions.push(`axis.${optionsKey}`);
      options.axes.forEach((axis) => {
        if (axis[optionsKey]) {
          delete axis[optionsKey];
        }
      });
    } else if (type === "series") {
      if (!((_c = options.series) == null ? void 0 : _c.some((series) => series.type === identifier)))
        continue;
      usedOptions.push(`series[type=${identifier}]`);
      options.series = options.series.filter((series) => series.type !== identifier);
    } else if (type === "series-option") {
      if (!((_d = options.series) == null ? void 0 : _d.some((series) => series[optionsKey])))
        continue;
      usedOptions.push(`series.${optionsKey}`);
      options.series.forEach((series) => {
        if (series[optionsKey]) {
          delete series[optionsKey];
        }
      });
    }
  }
  if (usedOptions.length > 0) {
    Logger.warnOnce(
      [
        `unable to use these enterprise features as 'ag-charts-enterprise' has not been loaded:`,
        ``,
        ...usedOptions,
        ``,
        "See: https://charts.ag-grid.com/javascript/installation/"
      ].join("\n")
    );
  }
}
var DEFAULT_BACKGROUND_FILL = "white";
var palette = {
  fills: Array.from(Object.values(DEFAULT_FILLS)),
  strokes: Array.from(Object.values(DEFAULT_STROKES))
};
var CHART_TYPE_CONFIG = {
  get cartesian() {
    return { seriesTypes: CHART_TYPES.cartesianTypes, commonOptions: ["zoom", "navigator"] };
  },
  get polar() {
    return { seriesTypes: CHART_TYPES.polarTypes, commonOptions: [] };
  },
  get hierarchy() {
    return { seriesTypes: CHART_TYPES.hierarchyTypes, commonOptions: [] };
  }
};
var CHART_TYPE_SPECIFIC_COMMON_OPTIONS = Object.values(CHART_TYPE_CONFIG).reduce((r, { commonOptions }) => [...r, ...commonOptions], []);
function resolvePartialPalette(partialPalette, basePalette) {
  var _a, _b;
  if (partialPalette == null)
    return null;
  return {
    fills: (_a = partialPalette.fills) != null ? _a : basePalette.fills,
    strokes: (_b = partialPalette.strokes) != null ? _b : basePalette.strokes
  };
}
var _ChartTheme = class _ChartTheme2 {
  getPalette() {
    return palette;
  }
  static getAxisDefaults() {
    return {
      top: {},
      right: {},
      bottom: {},
      left: {},
      title: {
        enabled: false,
        text: "Axis Title",
        spacing: 25,
        fontStyle: void 0,
        fontWeight: FONT_WEIGHT2.NORMAL,
        fontSize: FONT_SIZE.MEDIUM,
        fontFamily: DEFAULT_FONT_FAMILY,
        color: DEFAULT_LABEL_COLOUR
      },
      label: {
        fontStyle: void 0,
        fontWeight: void 0,
        fontSize: FONT_SIZE.SMALL,
        fontFamily: DEFAULT_FONT_FAMILY,
        padding: 5,
        rotation: void 0,
        color: DEFAULT_LABEL_COLOUR,
        formatter: void 0,
        avoidCollisions: true
      },
      line: {
        enabled: true,
        width: 1,
        color: DEFAULT_AXIS_LINE_COLOUR
      },
      tick: {
        enabled: false,
        width: 1,
        color: DEFAULT_AXIS_LINE_COLOUR
      },
      gridLine: {
        enabled: true,
        style: [
          {
            stroke: DEFAULT_AXIS_GRID_COLOUR,
            lineDash: []
          }
        ]
      },
      crossLines: {
        enabled: false,
        fill: DEFAULT_CROSS_LINES_COLOUR,
        stroke: DEFAULT_CROSS_LINES_COLOUR,
        fillOpacity: 0.1,
        strokeWidth: 1,
        label: {
          enabled: false,
          fontStyle: void 0,
          fontWeight: void 0,
          fontSize: FONT_SIZE.SMALL,
          fontFamily: DEFAULT_FONT_FAMILY,
          padding: 5,
          color: DEFAULT_LABEL_COLOUR
        }
      }
    };
  }
  static getSeriesDefaults() {
    return {
      tooltip: {
        enabled: true,
        renderer: void 0
      },
      visible: true,
      showInLegend: true,
      highlightStyle: {
        item: {
          fill: "rgba(255,255,255, 0.33)",
          stroke: `rgba(0, 0, 0, 0.4)`,
          strokeWidth: 2
        },
        series: {
          dimOpacity: 1
        },
        text: {
          color: "black"
        }
      },
      nodeClickRange: "exact"
    };
  }
  static getCartesianSeriesMarkerDefaults() {
    return {
      enabled: true,
      shape: "circle",
      size: 7,
      strokeWidth: 1,
      formatter: void 0
    };
  }
  static getLegendItemMarkerDefaults() {
    return {
      shape: void 0,
      size: 15,
      padding: 8
    };
  }
  static getCaptionWrappingDefaults() {
    return "hyphenate";
  }
  static getChartDefaults() {
    return {
      background: {
        visible: true,
        fill: DEFAULT_BACKGROUND_COLOUR
      },
      padding: {
        top: 20,
        right: 20,
        bottom: 20,
        left: 20
      },
      title: {
        enabled: false,
        text: "Title",
        fontStyle: void 0,
        fontWeight: FONT_WEIGHT2.NORMAL,
        fontSize: FONT_SIZE.LARGE,
        fontFamily: DEFAULT_FONT_FAMILY,
        color: DEFAULT_LABEL_COLOUR,
        wrapping: _ChartTheme2.getCaptionWrappingDefaults()
      },
      subtitle: {
        enabled: false,
        text: "Subtitle",
        spacing: 20,
        fontStyle: void 0,
        fontWeight: void 0,
        fontSize: FONT_SIZE.MEDIUM,
        fontFamily: DEFAULT_FONT_FAMILY,
        color: DEFAULT_MUTED_LABEL_COLOUR,
        wrapping: _ChartTheme2.getCaptionWrappingDefaults()
      },
      footnote: {
        enabled: false,
        text: "Footnote",
        spacing: 20,
        fontStyle: void 0,
        fontWeight: void 0,
        fontSize: FONT_SIZE.MEDIUM,
        fontFamily: DEFAULT_FONT_FAMILY,
        color: "rgb(140, 140, 140)",
        wrapping: _ChartTheme2.getCaptionWrappingDefaults()
      },
      legend: {
        position: BOTTOM,
        spacing: 30,
        listeners: {},
        item: {
          paddingX: 16,
          paddingY: 8,
          marker: _ChartTheme2.getLegendItemMarkerDefaults(),
          label: {
            color: DEFAULT_LABEL_COLOUR,
            fontStyle: void 0,
            fontWeight: void 0,
            fontSize: FONT_SIZE.SMALL,
            fontFamily: DEFAULT_FONT_FAMILY,
            formatter: void 0
          }
        },
        reverseOrder: false,
        pagination: {
          marker: {
            size: 12
          },
          activeStyle: {
            fill: DEFAULT_LABEL_COLOUR
          },
          inactiveStyle: {
            fill: DEFAULT_MUTED_LABEL_COLOUR
          },
          highlightStyle: {
            fill: DEFAULT_LABEL_COLOUR
          },
          label: {
            color: DEFAULT_LABEL_COLOUR
          }
        }
      },
      tooltip: {
        enabled: true,
        range: "nearest",
        delay: 0
      },
      listeners: {}
    };
  }
  constructor(options) {
    var _a;
    options = deepMerge({}, options != null ? options : {});
    const { overrides = null, palette: palette11 = null } = options;
    const defaults = this.createChartConfigPerChartType(this.getDefaults());
    if (overrides) {
      const { common } = overrides;
      const applyOverrides = (seriesTypes, overrideOpts) => {
        if (!overrideOpts)
          return;
        for (const s of seriesTypes) {
          const seriesType = s;
          defaults[seriesType] = deepMerge(defaults[seriesType], overrideOpts);
        }
      };
      for (const [, { seriesTypes, commonOptions }] of Object.entries(CHART_TYPE_CONFIG)) {
        const cleanedCommon = __spreadValues({}, common);
        for (const commonKey of CHART_TYPE_SPECIFIC_COMMON_OPTIONS) {
          if (!commonOptions.includes(commonKey)) {
            delete cleanedCommon[commonKey];
          }
        }
        applyOverrides(seriesTypes, cleanedCommon);
      }
      CHART_TYPES.seriesTypes.forEach((s) => {
        const seriesType = s;
        if (overrides[seriesType]) {
          defaults[seriesType] = deepMerge(defaults[seriesType], overrides[seriesType]);
        }
      });
    }
    const basePalette = this.getPalette();
    this.palette = (_a = resolvePartialPalette(palette11, basePalette)) != null ? _a : basePalette;
    this.config = Object.freeze(this.templateTheme(defaults));
  }
  createChartConfigPerChartType(config) {
    Object.entries(CHART_TYPE_CONFIG).forEach(([nextType, { seriesTypes }]) => {
      const typeDefaults = getChartDefaults(nextType);
      seriesTypes.forEach((next) => {
        const alias = next;
        if (!config[alias]) {
          config[alias] = {};
          deepMerge(config[alias], typeDefaults);
        }
      });
    });
    return config;
  }
  getDefaults() {
    let defaults = {};
    const getChartTypeDefaults = (chartType2) => {
      return __spreadValues(__spreadValues(__spreadValues({}, getLegendThemeTemplates()), _ChartTheme2.getChartDefaults()), getChartDefaults(chartType2));
    };
    const getOverridesByType = (chartType2, seriesTypes) => {
      var _a, _b, _c, _d;
      const chartDefaults = getChartTypeDefaults(chartType2);
      const result = {};
      for (const seriesType of seriesTypes) {
        (_a = result[seriesType]) != null ? _a : result[seriesType] = deepMerge({}, chartDefaults);
        const axes = (_c = (_b = result[seriesType]).axes) != null ? _c : _b.axes = {};
        const template = getSeriesThemeTemplate(seriesType);
        if (template) {
          result[seriesType].series = deepMerge(result[seriesType].series, template);
        }
        for (const axisType of AXIS_TYPES.axesTypes) {
          const template2 = getAxisThemeTemplate(axisType);
          if (chartType2 === "cartesian") {
            axes[axisType] = deepMerge(
              axes[axisType],
              (_d = _ChartTheme2.cartesianAxisDefault[axisType]) != null ? _d : {}
            );
          }
          if (template2) {
            axes[axisType] = deepMerge(axes[axisType], template2);
          }
        }
      }
      return result;
    };
    defaults = deepMerge(defaults, getOverridesByType("cartesian", CHART_TYPES.cartesianTypes));
    defaults = deepMerge(defaults, getOverridesByType("polar", CHART_TYPES.polarTypes));
    defaults = deepMerge(defaults, getOverridesByType("hierarchy", CHART_TYPES.hierarchyTypes));
    return defaults;
  }
  templateTheme(themeTemplate) {
    const themeInstance = jsonClone(themeTemplate);
    const { extensions, properties } = this.getTemplateParameters();
    jsonWalk(themeInstance, (node) => {
      if (node["__extends__"]) {
        const key = node["__extends__"];
        const source = extensions.get(key);
        if (source == null) {
          throw new Error(`AG Charts - no template variable provided for: ${key}`);
        }
        Object.keys(source).forEach((key2) => {
          if (!(key2 in node)) {
            node[key2] = source[key2];
          }
        });
        delete node["__extends__"];
      }
      if (node["__overrides__"]) {
        const key = node["__overrides__"];
        const source = extensions.get(key);
        if (source == null) {
          throw new Error(`AG Charts - no template variable provided for: ${key}`);
        }
        Object.assign(node, source);
        delete node["__overrides__"];
      }
      if (Array.isArray(node)) {
        for (let i = 0; i < node.length; i++) {
          const symbol = node[i];
          if (properties.has(symbol)) {
            node[i] = properties.get(symbol);
          }
        }
      } else {
        for (const [name, value] of Object.entries(node)) {
          if (properties.has(value)) {
            node[name] = properties.get(value);
          }
        }
      }
    });
    return themeInstance;
  }
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: DEFAULT_FILLS.BLUE,
      stroke: DEFAULT_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: DEFAULT_FILLS.ORANGE,
      stroke: DEFAULT_STROKES.ORANGE
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: DEFAULT_FILLS.GRAY,
      stroke: DEFAULT_STROKES.GRAY
    };
  }
  getTemplateParameters() {
    const extensions = /* @__PURE__ */ new Map();
    extensions.set(EXTENDS_CHART_DEFAULTS, _ChartTheme2.getChartDefaults());
    extensions.set(EXTENDS_AXES_DEFAULTS, _ChartTheme2.getAxisDefaults());
    extensions.set(EXTENDS_LEGEND_DEFAULTS, _ChartTheme2.getChartDefaults().legend);
    extensions.set(EXTENDS_LEGEND_ITEM_DEFAULTS, _ChartTheme2.getChartDefaults().legend.item);
    extensions.set(EXTENDS_LEGEND_ITEM_MARKER_DEFAULTS, _ChartTheme2.getLegendItemMarkerDefaults());
    extensions.set(EXTENDS_AXES_LABEL_DEFAULTS, _ChartTheme2.getAxisDefaults().label);
    extensions.set(EXTENDS_AXES_LINE_DEFAULTS, _ChartTheme2.getAxisDefaults().line);
    extensions.set(EXTENDS_AXES_TICK_DEFAULTS, _ChartTheme2.getAxisDefaults().tick);
    extensions.set(EXTENDS_AXES_GRID_LINE_DEFAULTS, _ChartTheme2.getAxisDefaults().gridLine);
    extensions.set(EXTENDS_SERIES_DEFAULTS, _ChartTheme2.getSeriesDefaults());
    extensions.set(OVERRIDE_SERIES_LABEL_DEFAULTS, {});
    extensions.set(EXTENDS_CARTESIAN_MARKER_DEFAULTS, _ChartTheme2.getCartesianSeriesMarkerDefaults());
    const properties = /* @__PURE__ */ new Map();
    properties.set(DEFAULT_FONT_FAMILY, "Verdana, sans-serif");
    properties.set(DEFAULT_LABEL_COLOUR, "rgb(70, 70, 70)");
    properties.set(DEFAULT_INVERTED_LABEL_COLOUR, "white");
    properties.set(DEFAULT_MUTED_LABEL_COLOUR, "rgb(140, 140, 140)");
    properties.set(DEFAULT_AXIS_GRID_COLOUR, "rgb(224,234,241)");
    properties.set(DEFAULT_AXIS_LINE_COLOUR, "rgb(195, 195, 195)");
    properties.set(DEFAULT_CROSS_LINES_COLOUR, "rgb(70, 70, 70)");
    properties.set(DEFAULT_INSIDE_SERIES_LABEL_COLOUR, DEFAULT_BACKGROUND_FILL);
    properties.set(DEFAULT_BACKGROUND_COLOUR, DEFAULT_BACKGROUND_FILL);
    properties.set(DEFAULT_SHADOW_COLOUR, "rgba(0, 0, 0, 0.5)");
    properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      DEFAULT_FILLS.ORANGE,
      DEFAULT_FILLS.YELLOW,
      DEFAULT_FILLS.GREEN
    ]);
    properties.set(DEFAULT_HIERARCHY_FILLS, ["#ffffff", "#e0e5ea", "#c1ccd5", "#a3b4c1", "#859cad"]);
    properties.set(DEFAULT_HIERARCHY_STROKES, ["#ffffff", "#c5cbd1", "#a4b1bd", "#8498a9", "#648096"]);
    properties.set(DEFAULT_POLAR_SERIES_STROKE, DEFAULT_BACKGROUND_FILL);
    properties.set(DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS, _ChartTheme2.getWaterfallSeriesDefaultPositiveColors());
    properties.set(DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS, _ChartTheme2.getWaterfallSeriesDefaultNegativeColors());
    properties.set(DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS, _ChartTheme2.getWaterfallSeriesDefaultTotalColors());
    properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _ChartTheme2.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return {
      extensions,
      properties
    };
  }
};
_ChartTheme.cartesianAxisDefault = {
  number: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults()), {
    line: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults().line), {
      enabled: false
    })
  }),
  log: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults()), {
    base: 10,
    line: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults().line), {
      enabled: false
    })
  }),
  category: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults()), {
    groupPaddingInner: 0.1,
    label: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults().label), {
      autoRotate: true
    }),
    gridLine: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults().gridLine), {
      enabled: false
    })
  }),
  "grouped-category": __spreadValues({}, _ChartTheme.getAxisDefaults()),
  time: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults()), {
    gridLine: __spreadProps(__spreadValues({}, _ChartTheme.getAxisDefaults().gridLine), {
      enabled: false
    })
  })
};
var ChartTheme = _ChartTheme;
function groupSeriesByType(seriesOptions) {
  var _a, _b, _c;
  const groupMap = {};
  const stackMap = {};
  const defaultUnstackedGroup = "default-ag-charts-group";
  const result = [];
  for (const s of seriesOptions) {
    const type = (_a = s.type) != null ? _a : "line";
    const stackable = isStackableSeries(type);
    const groupable = isGroupableSeries(type);
    if (!stackable && !groupable) {
      result.push({ type: "ungrouped", opts: [s] });
      continue;
    }
    const { stacked: sStacked, stackGroup: sStackGroup, grouped: sGrouped = void 0, xKey } = s;
    const stacked = sStackGroup != null || sStacked === true;
    const grouped = sGrouped === true;
    let groupingKey = [sStackGroup != null ? sStackGroup : sStacked === true ? "stacked" : void 0, grouped ? "grouped" : void 0].filter((v) => v != null).join("-");
    if (!groupingKey) {
      groupingKey = defaultUnstackedGroup;
    }
    const indexKey = `${type}-${xKey}-${groupingKey}`;
    if (stacked && stackable) {
      const updated = (_b = stackMap[indexKey]) != null ? _b : stackMap[indexKey] = { type: "stack", opts: [] };
      if (updated.opts.length === 0)
        result.push(updated);
      updated.opts.push(s);
    } else if (grouped && groupable) {
      const updated = (_c = groupMap[indexKey]) != null ? _c : groupMap[indexKey] = { type: "group", opts: [] };
      if (updated.opts.length === 0)
        result.push(updated);
      updated.opts.push(s);
    } else {
      result.push({ type: "ungrouped", opts: [s] });
    }
  }
  return result;
}
function processSeriesOptions(_opts, seriesOptions) {
  var _a;
  const result = [];
  const preprocessed = seriesOptions.map((series) => {
    var _a2;
    const sType = (_a2 = series.type) != null ? _a2 : "line";
    const groupable = isGroupableSeries(sType);
    const stackable = isStackableSeries(sType);
    const stackedByDefault = isSeriesStackedByDefault(sType);
    if (series.grouped && !groupable) {
      Logger.warnOnce(`unsupported grouping of series type: ${sType}`);
    }
    if (series.stacked && !stackable) {
      Logger.warnOnce(`unsupported stacking of series type: ${sType}`);
    }
    if (!groupable && !stackable) {
      return series;
    }
    let stacked = false;
    let grouped2 = false;
    if (series.stacked === void 0 && series.grouped === void 0) {
      stacked = stackable && stackedByDefault;
      grouped2 = groupable && !stacked;
    } else if (series.stacked === void 0) {
      stacked = stackable && stackedByDefault && !(series.grouped && groupable);
      grouped2 = groupable && !stacked && !!series.grouped;
    } else if (series.grouped === void 0) {
      stacked = stackable && series.stacked;
      grouped2 = groupable && !stacked;
    } else {
      stacked = stackable && series.stacked;
      grouped2 = groupable && !stacked && series.grouped;
    }
    return __spreadProps(__spreadValues({}, series), { stacked, grouped: grouped2 });
  });
  const grouped = groupSeriesByType(preprocessed);
  const groupCount2 = grouped.reduce(
    (result2, next) => {
      var _a2, _b;
      if (next.type === "ungrouped")
        return result2;
      const seriesType = (_a2 = next.opts[0].type) != null ? _a2 : "line";
      (_b = result2[seriesType]) != null ? _b : result2[seriesType] = 0;
      result2[seriesType] += next.type === "stack" ? 1 : next.opts.length;
      return result2;
    },
    {}
  );
  const groupIdx = {};
  const addSeriesGroupingMeta = (group2) => {
    var _a2, _b;
    let stackIdx = 0;
    const seriesType = (_a2 = group2.opts[0].type) != null ? _a2 : "line";
    (_b = groupIdx[seriesType]) != null ? _b : groupIdx[seriesType] = 0;
    if (group2.type === "stack") {
      for (const opts of group2.opts) {
        opts.seriesGrouping = {
          groupIndex: groupIdx[seriesType],
          groupCount: groupCount2[seriesType],
          stackIndex: stackIdx++,
          stackCount: group2.opts.length
        };
      }
      groupIdx[seriesType]++;
    } else if (group2.type === "group") {
      for (const opts of group2.opts) {
        opts.seriesGrouping = {
          groupIndex: groupIdx[seriesType],
          groupCount: groupCount2[seriesType],
          stackIndex: 0,
          stackCount: 0
        };
        groupIdx[seriesType]++;
      }
    } else {
      for (const opts of group2.opts) {
        opts.seriesGrouping = void 0;
      }
    }
    return group2.opts;
  };
  Debug.create(true, "opts")("processSeriesOptions() - series grouping: ", grouped);
  for (const group2 of grouped) {
    const seriesType = (_a = group2.opts[0].type) != null ? _a : "line";
    if (isGroupableSeries(seriesType) || isStackableSeries(seriesType)) {
      result.push(...addSeriesGroupingMeta(group2));
    } else {
      result.push(...group2.opts);
    }
  }
  return result;
}
var DEFAULT_DARK_BACKGROUND_FILL = "#192232";
var DEFAULT_DARK_FILLS = {
  BLUE: "#5090dc",
  ORANGE: "#ffa03a",
  GREEN: "#459d55",
  CYAN: "#34bfe1",
  YELLOW: "#e1cc00",
  VIOLET: "#9669cb",
  GRAY: "#b5b5b5",
  MAGENTA: "#bd5aa7",
  BROWN: "#8a6224",
  RED: "#ef5452"
};
var DEFAULT_DARK_STROKES = {
  BLUE: "#74a8e6",
  ORANGE: "#ffbe70",
  GREEN: "#6cb176",
  CYAN: "#75d4ef",
  YELLOW: "#f6e559",
  VIOLET: "#aa86d8",
  GRAY: "#a1a1a1",
  MAGENTA: "#ce7ab9",
  BROWN: "#997b52",
  RED: "#ff7872"
};
var palette2 = {
  fills: Array.from(Object.values(DEFAULT_DARK_FILLS)),
  strokes: Array.from(Object.values(DEFAULT_DARK_STROKES))
};
var DarkTheme = class _DarkTheme extends ChartTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: DEFAULT_DARK_FILLS.BLUE,
      stroke: DEFAULT_DARK_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: DEFAULT_DARK_FILLS.ORANGE,
      stroke: DEFAULT_DARK_STROKES.ORANGE
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: DEFAULT_DARK_FILLS.GRAY,
      stroke: DEFAULT_DARK_STROKES.GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _DarkTheme.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _DarkTheme.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS, _DarkTheme.getWaterfallSeriesDefaultTotalColors());
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _DarkTheme.getWaterfallSeriesDefaultTotalColors().stroke
    );
    result.properties.set(DEFAULT_POLAR_SERIES_STROKE, DEFAULT_DARK_BACKGROUND_FILL);
    result.properties.set(DEFAULT_LABEL_COLOUR, "white");
    result.properties.set(DEFAULT_MUTED_LABEL_COLOUR, "#7D91A0");
    result.properties.set(DEFAULT_AXIS_GRID_COLOUR, "#545A6E");
    result.properties.set(DEFAULT_CROSS_LINES_COLOUR, "white");
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      DEFAULT_DARK_FILLS.ORANGE,
      DEFAULT_DARK_FILLS.YELLOW,
      DEFAULT_DARK_FILLS.GREEN
    ]);
    result.properties.set(DEFAULT_HIERARCHY_FILLS, ["#192834", "#253746", "#324859", "#3f596c", "#4d6a80"]);
    result.properties.set(DEFAULT_HIERARCHY_STROKES, ["#192834", "#3b5164", "#496275", "#577287", "#668399"]);
    result.properties.set(DEFAULT_BACKGROUND_COLOUR, DEFAULT_DARK_BACKGROUND_FILL);
    result.properties.set(DEFAULT_INSIDE_SERIES_LABEL_COLOUR, DEFAULT_DARK_BACKGROUND_FILL);
    return result;
  }
  getPalette() {
    return palette2;
  }
  constructor(options) {
    super(options);
  }
};
var MATERIAL_DARK_FILLS = {
  BLUE: "#2196F3",
  ORANGE: "#FF9800",
  GREEN: "#4CAF50",
  CYAN: "#00BCD4",
  YELLOW: "#FFEB3B",
  VIOLET: "#7E57C2",
  GRAY: "#9E9E9E",
  MAGENTA: "#F06292",
  BROWN: "#795548",
  RED: "#F44336"
};
var MATERIAL_DARK_STROKES = {
  BLUE: "#90CAF9",
  ORANGE: "#FFCC80",
  GREEN: "#A5D6A7",
  CYAN: "#80DEEA",
  YELLOW: "#FFF9C4",
  VIOLET: "#B39DDB",
  GRAY: "#E0E0E0",
  MAGENTA: "#F48FB1",
  BROWN: "#A1887F",
  RED: "#EF9A9A"
};
var palette3 = {
  fills: Array.from(Object.values(MATERIAL_DARK_FILLS)),
  strokes: Array.from(Object.values(MATERIAL_DARK_STROKES))
};
var MaterialDark = class _MaterialDark extends DarkTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: MATERIAL_DARK_FILLS.BLUE,
      stroke: MATERIAL_DARK_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: MATERIAL_DARK_FILLS.RED,
      stroke: MATERIAL_DARK_STROKES.RED
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: MATERIAL_DARK_FILLS.GRAY,
      stroke: MATERIAL_DARK_STROKES.GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _MaterialDark.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _MaterialDark.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS,
      _MaterialDark.getWaterfallSeriesDefaultTotalColors()
    );
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      MATERIAL_DARK_FILLS.ORANGE,
      MATERIAL_DARK_FILLS.YELLOW,
      MATERIAL_DARK_FILLS.GREEN
    ]);
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _MaterialDark.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return result;
  }
  getPalette() {
    return palette3;
  }
};
var MATERIAL_LIGHT_FILLS = {
  BLUE: "#2196F3",
  ORANGE: "#FF9800",
  GREEN: "#4CAF50",
  CYAN: "#00BCD4",
  YELLOW: "#FFEB3B",
  VIOLET: "#7E57C2",
  GRAY: "#9E9E9E",
  MAGENTA: "#F06292",
  BROWN: "#795548",
  RED: "#F44336"
};
var MATERIAL_LIGHT_STROKES = {
  BLUE: "#1565C0",
  ORANGE: "#E65100",
  GREEN: "#2E7D32",
  CYAN: "#00838F",
  YELLOW: "#F9A825",
  VIOLET: "#4527A0",
  GRAY: "#616161",
  MAGENTA: "#C2185B",
  BROWN: "#4E342E",
  RED: "#B71C1C"
};
var palette4 = {
  fills: Array.from(Object.values(MATERIAL_LIGHT_FILLS)),
  strokes: Array.from(Object.values(MATERIAL_LIGHT_STROKES))
};
var MaterialLight = class _MaterialLight extends ChartTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: MATERIAL_LIGHT_FILLS.BLUE,
      stroke: MATERIAL_LIGHT_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: MATERIAL_LIGHT_FILLS.RED,
      stroke: MATERIAL_LIGHT_STROKES.RED
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: MATERIAL_LIGHT_FILLS.GRAY,
      stroke: MATERIAL_LIGHT_STROKES.GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _MaterialLight.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _MaterialLight.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS,
      _MaterialLight.getWaterfallSeriesDefaultTotalColors()
    );
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      MATERIAL_LIGHT_FILLS.ORANGE,
      MATERIAL_LIGHT_FILLS.YELLOW,
      MATERIAL_LIGHT_FILLS.GREEN
    ]);
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _MaterialLight.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return result;
  }
  getPalette() {
    return palette4;
  }
};
var POLYCHROMA_DARK_FILLS = {
  BLUE: "#436ff4",
  PURPLE: "#9a7bff",
  MAGENTA: "#d165d2",
  PINK: "#f0598b",
  RED: "#f47348",
  ORANGE: "#f2a602",
  YELLOW: "#e9e201",
  GREEN: "#21b448",
  CYAN: "#00b9a2",
  MODERATE_BLUE: "#00aee4"
};
var POLYCHROMA_DARK_STROKES = {
  BLUE: "#6698ff",
  PURPLE: "#c0a3ff",
  MAGENTA: "#fc8dfc",
  PINK: "#ff82b1",
  RED: "#ff9b70",
  ORANGE: "#ffcf4e",
  YELLOW: "#ffff58",
  GREEN: "#58dd70",
  CYAN: "#51e2c9",
  MODERATE_BLUE: "#4fd7ff"
};
var POLYCHROMA_DARK_FILL_GRAY = "#bbbbbb";
var POLYCHROMA_DARK_STROKE_GRAY = "#eeeeee";
var palette5 = {
  fills: Array.from(Object.values(POLYCHROMA_DARK_FILLS)),
  strokes: Array.from(Object.values(POLYCHROMA_DARK_STROKES))
};
var PolychromaDark = class _PolychromaDark extends DarkTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: POLYCHROMA_DARK_FILLS.BLUE,
      stroke: POLYCHROMA_DARK_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: POLYCHROMA_DARK_FILLS.RED,
      stroke: POLYCHROMA_DARK_STROKES.RED
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: POLYCHROMA_DARK_FILL_GRAY,
      stroke: POLYCHROMA_DARK_STROKE_GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _PolychromaDark.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _PolychromaDark.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS,
      _PolychromaDark.getWaterfallSeriesDefaultTotalColors()
    );
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      POLYCHROMA_DARK_FILLS.BLUE,
      POLYCHROMA_DARK_FILLS.RED
    ]);
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _PolychromaDark.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return result;
  }
  getPalette() {
    return palette5;
  }
};
var POLYCHROMA_LIGHT_FILLS = {
  BLUE: "#436ff4",
  PURPLE: "#9a7bff",
  MAGENTA: "#d165d2",
  PINK: "#f0598b",
  RED: "#f47348",
  ORANGE: "#f2a602",
  YELLOW: "#e9e201",
  GREEN: "#21b448",
  CYAN: "#00b9a2",
  MODERATE_BLUE: "#00aee4"
};
var POLYCHROMA_LIGHT_STROKES = {
  BLUE: "#2346c9",
  PURPLE: "#7653d4",
  MAGENTA: "#a73da9",
  PINK: "#c32d66",
  RED: "#c84b1c",
  ORANGE: "#c87f00",
  YELLOW: "#c1b900",
  GREEN: "#008c1c",
  CYAN: "#00927c",
  MODERATE_BLUE: "#0087bb"
};
var POLYCHROMA_LIGHT_FILL_GRAY = "#bbbbbb";
var POLYCHROMA_LIGHT_STROKE_GRAY = "#888888";
var palette6 = {
  fills: Array.from(Object.values(POLYCHROMA_LIGHT_FILLS)),
  strokes: Array.from(Object.values(POLYCHROMA_LIGHT_STROKES))
};
var PolychromaLight = class _PolychromaLight extends ChartTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: POLYCHROMA_LIGHT_FILLS.BLUE,
      stroke: POLYCHROMA_LIGHT_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: POLYCHROMA_LIGHT_FILLS.RED,
      stroke: POLYCHROMA_LIGHT_STROKES.RED
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: POLYCHROMA_LIGHT_FILL_GRAY,
      stroke: POLYCHROMA_LIGHT_STROKE_GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _PolychromaLight.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _PolychromaLight.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS,
      _PolychromaLight.getWaterfallSeriesDefaultTotalColors()
    );
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      POLYCHROMA_LIGHT_FILLS.BLUE,
      POLYCHROMA_LIGHT_FILLS.RED
    ]);
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _PolychromaLight.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return result;
  }
  getPalette() {
    return palette6;
  }
};
var SHEETS_DARK_FILLS = {
  BLUE: "#4472C4",
  ORANGE: "#ED7D31",
  GRAY: "#A5A5A5",
  YELLOW: "#FFC000",
  MODERATE_BLUE: "#5B9BD5",
  GREEN: "#70AD47",
  DARK_GRAY: "#7B7B7B",
  DARK_BLUE: "#264478",
  VERY_DARK_GRAY: "#636363",
  DARK_YELLOW: "#997300"
};
var SHEETS_DARK_STROKES = {
  BLUE: "#6899ee",
  ORANGE: "#ffa55d",
  GRAY: "#cdcdcd",
  YELLOW: "#ffea53",
  MODERATE_BLUE: "#82c3ff",
  GREEN: "#96d56f",
  DARK_GRAY: "#a1a1a1",
  DARK_BLUE: "#47689f",
  VERY_DARK_GRAY: "#878787",
  DARK_YELLOW: "#c0993d"
};
var palette7 = {
  fills: Array.from(Object.values(SHEETS_DARK_FILLS)),
  strokes: Array.from(Object.values(SHEETS_DARK_STROKES))
};
var SheetsDark = class _SheetsDark extends DarkTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: SHEETS_DARK_FILLS.BLUE,
      stroke: SHEETS_DARK_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: SHEETS_DARK_FILLS.ORANGE,
      stroke: SHEETS_DARK_STROKES.ORANGE
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: SHEETS_DARK_FILLS.GRAY,
      stroke: SHEETS_DARK_STROKES.GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _SheetsDark.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _SheetsDark.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS,
      _SheetsDark.getWaterfallSeriesDefaultTotalColors()
    );
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      SHEETS_DARK_FILLS.ORANGE,
      SHEETS_DARK_FILLS.YELLOW,
      SHEETS_DARK_FILLS.GREEN
    ]);
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _SheetsDark.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return result;
  }
  getPalette() {
    return palette7;
  }
};
var SHEETS_LIGHT_FILLS = {
  BLUE: "#5281d5",
  ORANGE: "#ff8d44",
  GRAY: "#b5b5b5",
  YELLOW: "#ffd02f",
  MODERATE_BLUE: "#6aabe6",
  GREEN: "#7fbd57",
  DARK_GRAY: "#8a8a8a",
  DARK_BLUE: "#335287",
  VERY_DARK_GRAY: "#717171",
  DARK_YELLOW: "#a98220"
};
var SHEETS_LIGHT_STROKES = {
  BLUE: "#214d9b",
  ORANGE: "#c25600",
  GRAY: "#7f7f7f",
  YELLOW: "#d59800",
  MODERATE_BLUE: "#3575ac",
  GREEN: "#4b861a",
  DARK_GRAY: "#575757",
  DARK_BLUE: "#062253",
  VERY_DARK_GRAY: "#414141",
  DARK_YELLOW: "#734f00"
};
var palette8 = {
  fills: Array.from(Object.values(SHEETS_LIGHT_FILLS)),
  strokes: Array.from(Object.values(SHEETS_LIGHT_STROKES))
};
var SheetsLight = class _SheetsLight extends ChartTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: SHEETS_LIGHT_FILLS.BLUE,
      stroke: SHEETS_LIGHT_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: SHEETS_LIGHT_FILLS.ORANGE,
      stroke: SHEETS_LIGHT_STROKES.ORANGE
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: SHEETS_LIGHT_FILLS.GRAY,
      stroke: SHEETS_LIGHT_STROKES.GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _SheetsLight.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _SheetsLight.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS,
      _SheetsLight.getWaterfallSeriesDefaultTotalColors()
    );
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      SHEETS_LIGHT_FILLS.ORANGE,
      SHEETS_LIGHT_FILLS.YELLOW,
      SHEETS_LIGHT_FILLS.GREEN
    ]);
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _SheetsLight.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return result;
  }
  getPalette() {
    return palette8;
  }
};
var VIVID_DARK_FILLS = {
  BLUE: "#0083ff",
  ORANGE: "#ff6600",
  GREEN: "#00af00",
  CYAN: "#00ccff",
  YELLOW: "#f7c700",
  VIOLET: "#ac26ff",
  GRAY: "#a7a7b7",
  MAGENTA: "#e800c5",
  BROWN: "#b54300",
  RED: "#ff0000"
};
var VIVID_DARK_STROKES = {
  BLUE: "#67b7ff",
  ORANGE: "#ffc24d",
  GREEN: "#5cc86f",
  CYAN: "#54ebff",
  VIOLET: "#c18aff",
  YELLOW: "#fff653",
  GRAY: "#aeaeae",
  MAGENTA: "#f078d4",
  BROWN: "#ba8438",
  RED: "#ff726e"
};
var palette9 = {
  fills: Array.from(Object.values(VIVID_DARK_FILLS)),
  strokes: Array.from(Object.values(VIVID_DARK_STROKES))
};
var VividDark = class _VividDark extends DarkTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: VIVID_DARK_FILLS.BLUE,
      stroke: VIVID_DARK_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: VIVID_DARK_FILLS.ORANGE,
      stroke: VIVID_DARK_STROKES.ORANGE
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: VIVID_DARK_FILLS.GRAY,
      stroke: VIVID_DARK_STROKES.GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _VividDark.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _VividDark.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS, _VividDark.getWaterfallSeriesDefaultTotalColors());
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      VIVID_DARK_FILLS.ORANGE,
      VIVID_DARK_FILLS.YELLOW,
      VIVID_DARK_FILLS.GREEN
    ]);
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _VividDark.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return result;
  }
  getPalette() {
    return palette9;
  }
};
var VIVID_FILLS = {
  BLUE: "#0083ff",
  ORANGE: "#ff6600",
  GREEN: "#00af00",
  CYAN: "#00ccff",
  YELLOW: "#f7c700",
  VIOLET: "#ac26ff",
  GRAY: "#a7a7b7",
  MAGENTA: "#e800c5",
  BROWN: "#b54300",
  RED: "#ff0000"
};
var VIVID_STROKES = {
  BLUE: "#0f68c0",
  ORANGE: "#d47100",
  GREEN: "#007922",
  CYAN: "#009ac2",
  VIOLET: "#bca400",
  YELLOW: "#753cac",
  GRAY: "#646464",
  MAGENTA: "#9b2685",
  BROWN: "#6c3b00",
  RED: "#cb0021"
};
var palette10 = {
  fills: Array.from(Object.values(VIVID_FILLS)),
  strokes: Array.from(Object.values(VIVID_STROKES))
};
var VividLight = class _VividLight extends ChartTheme {
  static getWaterfallSeriesDefaultPositiveColors() {
    return {
      fill: VIVID_FILLS.BLUE,
      stroke: VIVID_STROKES.BLUE
    };
  }
  static getWaterfallSeriesDefaultNegativeColors() {
    return {
      fill: VIVID_FILLS.ORANGE,
      stroke: VIVID_STROKES.ORANGE
    };
  }
  static getWaterfallSeriesDefaultTotalColors() {
    return {
      fill: VIVID_FILLS.GRAY,
      stroke: VIVID_STROKES.GRAY
    };
  }
  getTemplateParameters() {
    const result = super.getTemplateParameters();
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
      _VividLight.getWaterfallSeriesDefaultPositiveColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
      _VividLight.getWaterfallSeriesDefaultNegativeColors()
    );
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS,
      _VividLight.getWaterfallSeriesDefaultTotalColors()
    );
    result.properties.set(DEFAULT_DIVERGING_SERIES_COLOUR_RANGE, [
      VIVID_FILLS.ORANGE,
      VIVID_FILLS.YELLOW,
      VIVID_FILLS.GREEN
    ]);
    result.properties.set(
      DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
      _VividLight.getWaterfallSeriesDefaultTotalColors().stroke
    );
    return result;
  }
  getPalette() {
    return palette10;
  }
};
var lightTheme = () => new ChartTheme();
var darkTheme = () => new DarkTheme();
var lightThemes = {
  undefined: lightTheme,
  null: lightTheme,
  "ag-default": lightTheme,
  "ag-sheets": () => new SheetsLight(),
  "ag-polychroma": () => new PolychromaLight(),
  "ag-vivid": () => new VividLight(),
  "ag-material": () => new MaterialLight()
};
var darkThemes = {
  undefined: darkTheme,
  null: darkTheme,
  "ag-default-dark": darkTheme,
  "ag-sheets-dark": () => new SheetsDark(),
  "ag-polychroma-dark": () => new PolychromaDark(),
  "ag-vivid-dark": () => new VividDark(),
  "ag-material-dark": () => new MaterialDark()
};
var themes = __spreadValues(__spreadValues({}, darkThemes), lightThemes);
function validateChartThemeObject(unknownObject) {
  if (unknownObject === null) {
    return void 0;
  }
  let valid = true;
  const { baseTheme, palette: palette11, overrides } = unknownObject;
  if (baseTheme !== void 0 && typeof baseTheme !== "string" && typeof baseTheme !== "object") {
    Logger.warn(`invalid theme.baseTheme type ${typeof baseTheme}, expected (string | object).`);
    valid = false;
  }
  if (overrides !== void 0 && typeof overrides !== "object") {
    Logger.warn(`invalid theme.overrides type ${typeof overrides}, expected object.`);
    valid = false;
  }
  if (typeof palette11 === "object") {
    if (palette11 !== null) {
      const { fills, strokes } = palette11;
      if (fills !== void 0 && !Array.isArray(fills)) {
        Logger.warn(`theme.overrides.fills must be undefined or an array`);
        valid = false;
      }
      if (strokes !== void 0 && !Array.isArray(strokes)) {
        Logger.warn(`theme.overrides.strokes must be undefined or an array`);
        valid = false;
      }
    }
  } else if (palette11 !== void 0) {
    Logger.warn(`invalid theme.palette type ${typeof palette11}, expected object.`);
    valid = false;
  }
  if (valid) {
    return unknownObject;
  }
  return void 0;
}
function validateChartTheme(value) {
  if (value === void 0 || typeof value === "string" || value instanceof ChartTheme) {
    return value;
  }
  if (typeof value === "object") {
    return validateChartThemeObject(value);
  }
  Logger.warn(`invalid theme value type ${typeof value}, expected object.`);
  return void 0;
}
function getChartTheme(unvalidatedValue) {
  var _a;
  let value = validateChartTheme(unvalidatedValue);
  if (value instanceof ChartTheme) {
    return value;
  }
  if (value === void 0 || typeof value === "string") {
    const stockTheme = themes[value];
    if (stockTheme) {
      return stockTheme();
    }
    Logger.warnOnce(`the theme [${value}] is invalid, using [ag-default] instead.`);
    return lightTheme();
  }
  const overrides = [];
  let palette11;
  while (typeof value === "object") {
    overrides.push((_a = value.overrides) != null ? _a : {});
    if (value.palette && palette11 == null) {
      palette11 = value.palette;
    }
    value = value.baseTheme;
  }
  overrides.reverse();
  const flattenedTheme = __spreadValues({
    baseTheme: value,
    overrides: jsonMerge(overrides)
  }, palette11 ? { palette: palette11 } : {});
  const baseTheme = flattenedTheme.baseTheme ? getChartTheme(flattenedTheme.baseTheme) : lightTheme();
  return new baseTheme.constructor(flattenedTheme);
}
function takeColours(context, colours, maxCount) {
  const result = [];
  for (let count2 = 0; count2 < maxCount; count2++) {
    result.push(colours[(count2 + context.colourIndex) % colours.length]);
  }
  return result;
}
var noDataCloneMergeOptions = {
  avoidDeepClone: ["data"]
};
function getGlobalTooltipPositionOptions(position) {
  if (position === void 0 || typeof position !== "object" || position === null) {
    return {};
  }
  const { type, xOffset, yOffset } = position;
  const AgTooltipPositionTypeMap = { pointer: true, node: true };
  const result = {};
  const isTooltipPositionType = (value) => Object.keys(AgTooltipPositionTypeMap).includes(value);
  if (typeof type === "string" && isTooltipPositionType(type)) {
    result.type = type;
  }
  if (typeof xOffset === "number" && !isNaN(xOffset) && isFinite(xOffset)) {
    result.xOffset = xOffset;
  }
  if (typeof yOffset === "number" && !isNaN(yOffset) && isFinite(yOffset)) {
    result.yOffset = yOffset;
  }
  return result;
}
function prepareOptions(options) {
  var _a, _b, _c, _d;
  sanityCheckOptions(options);
  const type = optionsType(options);
  const checkSeriesType = (type2) => {
    if (type2 != null && !(isSeriesOptionType(type2) || isEnterpriseSeriesType(type2) || getSeriesDefaults(type2))) {
      throw new Error(`AG Charts - unknown series type: ${type2}; expected one of: ${CHART_TYPES.seriesTypes}`);
    }
  };
  for (const { type: seriesType } of (_a = options.series) != null ? _a : []) {
    if (seriesType == null)
      continue;
    checkSeriesType(seriesType);
  }
  options = validateSoloSeries(options);
  let defaultSeriesType = "line";
  if (isAgCartesianChartOptions(options)) {
    defaultSeriesType = "line";
  } else if (isAgHierarchyChartOptions(options)) {
    defaultSeriesType = "treemap";
  } else if (isAgPolarChartOptions(options)) {
    defaultSeriesType = "pie";
  }
  let defaultOverrides = getSeriesDefaults(type);
  if (isDefaultAxisSwapNeeded(options)) {
    defaultOverrides = swapAxes(defaultOverrides);
  }
  defaultOverrides = executeCustomDefaultsFunctions(options, defaultOverrides);
  const conflictOverrides = resolveModuleConflicts(options);
  removeDisabledOptions(options);
  const globalTooltipPositionOptions = getGlobalTooltipPositionOptions((_b = options.tooltip) == null ? void 0 : _b.position);
  const { context, mergedOptions, axesThemes, seriesThemes, theme } = prepareMainOptions(
    defaultOverrides,
    options,
    conflictOverrides
  );
  mergedOptions.series = processSeriesOptions(
    mergedOptions,
    ((_c = mergedOptions.series) != null ? _c : []).map((s) => {
      var _a2;
      const type2 = (_a2 = s.type) != null ? _a2 : defaultSeriesType;
      const mergedSeries = mergeSeriesOptions(s, type2, seriesThemes, globalTooltipPositionOptions);
      if (type2 === "pie") {
        preparePieOptions(seriesThemes.pie, s, mergedSeries);
      }
      return mergedSeries;
    })
  ).map((s) => prepareSeries(context, s)).map((s) => theme.templateTheme(s));
  const checkAxisType = (type2) => {
    const isAxisType = isAxisOptionType(type2);
    if (!isAxisType) {
      Logger.warnOnce(`unknown axis type: ${type2}; expected one of: ${AXIS_TYPES.axesTypes}, ignoring.`);
    }
    return isAxisType;
  };
  if ("axes" in mergedOptions) {
    let validAxesTypes = true;
    for (const { type: axisType } of (_d = mergedOptions.axes) != null ? _d : []) {
      validAxesTypes && (validAxesTypes = checkAxisType(axisType));
    }
    const axisSource = validAxesTypes ? mergedOptions.axes : defaultOverrides.axes;
    mergedOptions.axes = axisSource == null ? void 0 : axisSource.map((axis) => {
      var _a2, _b2, _c2, _d2, _e;
      const axisType = axis.type;
      let axisDefaults;
      if (validAxesTypes) {
        axisDefaults = (_a2 = defaultOverrides.axes) == null ? void 0 : _a2.find(
          ({ type: type2 }) => type2 === axisType
        );
      }
      const axesTheme = jsonMerge([
        (_b2 = axesThemes[axisType]) != null ? _b2 : {},
        (_e = (_d2 = axesThemes[axisType]) == null ? void 0 : _d2[(_c2 = axis.position) != null ? _c2 : "unknown"]) != null ? _e : {},
        axisDefaults
      ]);
      return prepareAxis(axis, axesTheme);
    });
    prepareLegendEnabledOption(options, mergedOptions);
  }
  prepareEnabledOptions(options, mergedOptions);
  return mergedOptions;
}
function sanityCheckOptions(options) {
  const deprecatedArrayProps = {
    yKeys: "yKey",
    yNames: "yName"
  };
  Object.entries(deprecatedArrayProps).forEach(([oldProp, newProp]) => {
    var _a;
    if ((_a = options.series) == null ? void 0 : _a.some((s) => s[oldProp] != null)) {
      Logger.warnOnce(
        `Property [series.${oldProp}] is deprecated, please use [series.${newProp}] and multiple series instead.`
      );
    }
  });
}
function hasSoloSeries(options) {
  return options.some((series) => isSoloSeries(series.type));
}
function validateSoloSeries(options) {
  if (options.series === void 0 || options.series.length <= 1 || !hasSoloSeries(options.series)) {
    return options;
  }
  let series = [...options.series];
  if (isSoloSeries(series[0].type)) {
    Logger.warn(
      `series[0] of type '${series[0].type}' is incompatible with other series types. Only processing series[0]`
    );
    series = series.slice(0, 1);
  } else {
    const rejects = Array.from(new Set(series.filter((s) => isSoloSeries(s.type)).map((s) => s.type)));
    Logger.warnOnce(`Unable to mix these series types with the lead series type: ${rejects}`);
    series = series.filter((s) => !isSoloSeries(s.type));
  }
  return __spreadProps(__spreadValues({}, options), { series });
}
function mergeSeriesOptions(series, type, seriesThemes, globalTooltipPositionOptions) {
  var _a, _b;
  const mergedTooltipPosition = jsonMerge(
    [__spreadValues({}, globalTooltipPositionOptions), (_a = series.tooltip) == null ? void 0 : _a.position],
    noDataCloneMergeOptions
  );
  return jsonMerge(
    [
      (_b = seriesThemes[type]) != null ? _b : {},
      __spreadProps(__spreadValues({}, series), { type, tooltip: __spreadProps(__spreadValues({}, series.tooltip), { position: mergedTooltipPosition }) })
    ],
    noDataCloneMergeOptions
  );
}
function prepareMainOptions(defaultOverrides, options, conflictOverrides) {
  const { theme, cleanedTheme, axesThemes, seriesThemes, userPalette: partialPalette } = prepareTheme(options);
  const userPalette = resolvePartialPalette(partialPalette, theme.palette);
  const context = { colourIndex: 0, palette: theme.palette, userPalette, theme };
  defaultOverrides = theme.templateTheme(defaultOverrides);
  const mergedOptions = jsonMerge(
    [defaultOverrides, cleanedTheme, options, conflictOverrides],
    noDataCloneMergeOptions
  );
  if (!enterpriseModule.isEnterprise) {
    removeUsedEnterpriseOptions(mergedOptions);
  }
  return { context, mergedOptions, axesThemes, seriesThemes, theme };
}
function prepareTheme(options) {
  var _a;
  const theme = getChartTheme(options.theme);
  const themeConfig = theme.config[optionsType(options)];
  const seriesThemes = Object.entries(theme.config).reduce((result, [seriesType, { series }]) => {
    result[seriesType] = series;
    return result;
  }, {});
  const userTheme = options.theme;
  const userPalette = typeof userTheme === "object" && userTheme.palette ? userTheme.palette : null;
  return {
    theme,
    axesThemes: (_a = themeConfig == null ? void 0 : themeConfig["axes"]) != null ? _a : {},
    seriesThemes,
    cleanedTheme: jsonMerge([themeConfig != null ? themeConfig : {}, { axes: DELETE, series: DELETE }]),
    userPalette
  };
}
function prepareSeries(context, input, ...defaults) {
  const paletteOptions = calculateSeriesPalette(context, input);
  const removeOptions = { stacked: DELETE, grouped: DELETE };
  return jsonMerge([...defaults, paletteOptions, input, removeOptions], noDataCloneMergeOptions);
}
function calculateSeriesPalette(context, input) {
  const paletteFactory = getSeriesPaletteFactory(input.type);
  if (!paletteFactory) {
    return {};
  }
  const {
    palette: { fills = [], strokes = [] },
    userPalette,
    theme
  } = context;
  const colorsCount = Math.max(fills.length, strokes.length);
  return paletteFactory({
    userPalette,
    themeTemplateParameters: theme.getTemplateParameters(),
    colorsCount,
    takeColors: (count2) => {
      const colors = {
        fills: takeColours(context, fills, count2),
        strokes: takeColours(context, strokes, count2)
      };
      context.colourIndex += count2;
      return colors;
    }
  });
}
function prepareAxis(axis, axisTheme) {
  var _a, _b;
  const removeOptions = { top: DELETE, bottom: DELETE, left: DELETE, right: DELETE };
  if (axis.crossLines) {
    if (!Array.isArray(axis.crossLines)) {
      Logger.warn("axis[].crossLines should be an array.");
      axis.crossLines = [];
    }
    axis.crossLines = axis.crossLines.map((crossLine) => {
      var _a2;
      return jsonMerge([(_a2 = axisTheme.crossLines) != null ? _a2 : {}, crossLine]);
    });
  }
  const gridLineStyle = (_a = axisTheme.gridLine) == null ? void 0 : _a.style;
  if (((_b = axis.gridLine) == null ? void 0 : _b.style) !== void 0 && gridLineStyle !== void 0 && gridLineStyle.length > 0) {
    if (!Array.isArray(axis.gridLine.style)) {
      Logger.warn("axis[].gridLine.style should be an array.");
      axis.gridLine.style = [];
    }
    axis.gridLine.style = axis.gridLine.style.map((userStyle, index) => {
      if (userStyle.stroke === void 0 && userStyle.lineDash === void 0) {
        return userStyle;
      }
      const themeStyle = gridLineStyle[index % gridLineStyle.length];
      return jsonMerge([themeStyle, userStyle]);
    });
  }
  const cleanTheme = { crossLines: DELETE };
  return jsonMerge([axisTheme, cleanTheme, axis, removeOptions], noDataCloneMergeOptions);
}
function removeDisabledOptions(options) {
  jsonWalk(
    options,
    (userOptionsNode) => {
      if ("enabled" in userOptionsNode && userOptionsNode.enabled === false) {
        Object.keys(userOptionsNode).forEach((key) => {
          if (key === "enabled")
            return;
          delete userOptionsNode[key];
        });
      }
    },
    { skip: ["data", "theme"] }
  );
}
function prepareLegendEnabledOption(options, mergedOptions) {
  var _a, _b, _c, _d;
  if (!isDefined((_a = options.legend) == null ? void 0 : _a.enabled) && !isDefined((_b = mergedOptions.legend) == null ? void 0 : _b.enabled)) {
    (_c = mergedOptions.legend) != null ? _c : mergedOptions.legend = {};
    mergedOptions.legend.enabled = ((_d = options.series) != null ? _d : []).length > 1;
  }
}
function prepareEnabledOptions(options, mergedOptions) {
  jsonWalk(
    options,
    (visitingUserOpts, visitingMergedOpts) => {
      if (visitingMergedOpts && "enabled" in visitingMergedOpts && !visitingMergedOpts._enabledFromTheme && visitingUserOpts.enabled == null) {
        visitingMergedOpts.enabled = true;
      }
    },
    { skip: ["data", "theme"] },
    mergedOptions
  );
  jsonWalk(
    mergedOptions,
    (visitingMergedOpts) => {
      if (visitingMergedOpts._enabledFromTheme != null) {
        delete visitingMergedOpts._enabledFromTheme;
      }
    },
    { skip: ["data", "theme"] }
  );
}
function preparePieOptions(pieSeriesTheme, seriesOptions, mergedSeries) {
  if (isArray(seriesOptions.innerLabels)) {
    mergedSeries.innerLabels = seriesOptions.innerLabels.map(
      (innerLabel) => jsonMerge([pieSeriesTheme.innerLabels, innerLabel])
    );
  } else {
    mergedSeries.innerLabels = DELETE;
  }
}
var CARTESIAN_AXIS_POSITIONS2 = ["top", "right", "bottom", "left"];
var CARTESIAN_AXIS_TYPES2 = ["category", "grouped-category", "number", "log", "time"];
function hasCartesianAxisPosition(axis) {
  const allowedTypes = CARTESIAN_AXIS_TYPES2;
  return allowedTypes.includes(axis.type);
}
function isCartesianAxisOptions(options) {
  const allowedTypes = CARTESIAN_AXIS_TYPES2;
  return allowedTypes.includes(options.type);
}
function isAxisPosition(position) {
  const allowedPositions = CARTESIAN_AXIS_POSITIONS2;
  return typeof position === "string" && allowedPositions.includes(position);
}
var AxisPositionGuesser = class {
  constructor() {
    this.result = [];
    this.valid = [];
    this.invalid = [];
  }
  push(axis, options) {
    const { result, valid, invalid } = this;
    if (isCartesianAxisOptions(options)) {
      if (isAxisPosition(options.position)) {
        valid.push(axis);
      } else {
        invalid.push(axis);
      }
    }
    result.push(axis);
  }
  guessInvalidPositions() {
    const takenPosition = this.valid.filter((v) => hasCartesianAxisPosition(v)).map((v) => v.position).filter((v) => v !== void 0);
    const guesses = ["top", "right", "bottom", "left"];
    for (const invalidAxis of this.invalid) {
      let nextGuess = guesses.pop();
      while (takenPosition.includes(nextGuess) && nextGuess !== void 0) {
        nextGuess = guesses.pop();
      }
      if (nextGuess === void 0)
        break;
      invalidAxis.position = nextGuess;
    }
    return this.result;
  }
};
var _PolarChart = class _PolarChart2 extends Chart {
  constructor(specialOverrides, resources) {
    super(specialOverrides, resources);
    this.padding = new Padding(40);
    this.axisGroup.zIndex = 5;
  }
  performLayout() {
    return __async(this, null, function* () {
      const shrinkRect = yield __superGet(_PolarChart2.prototype, this, "performLayout").call(this);
      const fullSeriesRect = shrinkRect.clone();
      this.computeSeriesRect(shrinkRect);
      yield this.computeCircle(shrinkRect);
      this.axes.forEach((axis) => axis.update());
      this.hoverRect = shrinkRect;
      this.layoutService.dispatchLayoutComplete({
        type: "layout-complete",
        chart: { width: this.scene.width, height: this.scene.height },
        clipSeries: false,
        series: { rect: fullSeriesRect, paddedRect: shrinkRect, visible: true },
        axes: []
      });
      return shrinkRect;
    });
  }
  updateAxes(cx, cy, radius) {
    var _a, _b;
    const angleAxis = this.axes.find(
      (axis) => axis.direction === "x"
      /* X */
    );
    const radiusAxis = this.axes.find(
      (axis) => axis.direction === "y"
      /* Y */
    );
    if (!(angleAxis instanceof PolarAxis) || !(radiusAxis instanceof PolarAxis)) {
      return;
    }
    const angleScale = angleAxis.scale;
    const angles = (_a = angleScale.ticks) == null ? void 0 : _a.call(angleScale).map((value) => angleScale.convert(value));
    const innerRadiusRatio = radiusAxis.innerRadiusRatio;
    angleAxis.innerRadiusRatio = innerRadiusRatio;
    (_b = angleAxis.computeRange) == null ? void 0 : _b.call(angleAxis);
    angleAxis.gridLength = radius;
    radiusAxis.gridAngles = angles;
    radiusAxis.gridRange = angleAxis.range;
    radiusAxis.range = [radius, radius * innerRadiusRatio];
    [angleAxis, radiusAxis].forEach((axis) => {
      axis.translation.x = cx;
      axis.translation.y = cy;
      axis.calculateLayout();
    });
  }
  computeSeriesRect(shrinkRect) {
    const {
      seriesArea: { padding }
    } = this;
    shrinkRect.shrink(padding.left, "left");
    shrinkRect.shrink(padding.top, "top");
    shrinkRect.shrink(padding.right, "right");
    shrinkRect.shrink(padding.bottom, "bottom");
    this.seriesRect = shrinkRect;
    this.animationRect = shrinkRect;
  }
  computeCircle(seriesBox) {
    return __async(this, null, function* () {
      const polarSeries = this.series.filter((series) => {
        return series instanceof PolarSeries;
      });
      const polarAxes = this.axes.filter((axis) => {
        return axis instanceof PolarAxis;
      });
      const setSeriesCircle = (cx, cy, r) => {
        this.updateAxes(cx, cy, r);
        polarSeries.forEach((series) => {
          series.centerX = cx;
          series.centerY = cy;
          series.radius = r;
        });
        const pieSeries = polarSeries.filter((s) => s instanceof PieSeries);
        if (pieSeries.length > 1) {
          const innerRadii = pieSeries.map((series) => {
            const innerRadius = series.getInnerRadius();
            return { series, innerRadius };
          }).sort((a, b) => a.innerRadius - b.innerRadius);
          innerRadii[innerRadii.length - 1].series.surroundingRadius = void 0;
          for (let i = 0; i < innerRadii.length - 1; i++) {
            innerRadii[i].series.surroundingRadius = innerRadii[i + 1].innerRadius;
          }
        }
      };
      const centerX = seriesBox.x + seriesBox.width / 2;
      const centerY = seriesBox.y + seriesBox.height / 2;
      const initialRadius = Math.max(0, Math.min(seriesBox.width, seriesBox.height) / 2);
      let radius = initialRadius;
      setSeriesCircle(centerX, centerY, radius);
      const shake = (..._0) => __async(this, [..._0], function* ({ hideWhenNecessary = false } = {}) {
        const labelBoxes = [];
        for (const series of [...polarAxes, ...polarSeries]) {
          const box = yield series.computeLabelsBBox({ hideWhenNecessary }, seriesBox);
          if (box) {
            labelBoxes.push(box);
          }
        }
        if (labelBoxes.length === 0) {
          setSeriesCircle(centerX, centerY, initialRadius);
          return;
        }
        const labelBox = BBox.merge(labelBoxes);
        const refined = this.refineCircle(labelBox, radius, seriesBox);
        setSeriesCircle(refined.centerX, refined.centerY, refined.radius);
        if (refined.radius === radius) {
          return;
        }
        radius = refined.radius;
      });
      yield shake();
      yield shake();
      yield shake();
      yield shake({ hideWhenNecessary: true });
      yield shake({ hideWhenNecessary: true });
      return { radius, centerX, centerY };
    });
  }
  refineCircle(labelsBox, radius, seriesBox) {
    const minCircleRatio = 0.5;
    const circleLeft = -radius;
    const circleTop = -radius;
    const circleRight = radius;
    const circleBottom = radius;
    let padLeft = Math.max(0, circleLeft - labelsBox.x);
    let padTop = Math.max(0, circleTop - labelsBox.y);
    let padRight = Math.max(0, labelsBox.x + labelsBox.width - circleRight);
    let padBottom = Math.max(0, labelsBox.y + labelsBox.height - circleBottom);
    padLeft = padRight = Math.max(padLeft, padRight);
    padTop = padBottom = Math.max(padTop, padBottom);
    const availCircleWidth = seriesBox.width - padLeft - padRight;
    const availCircleHeight = seriesBox.height - padTop - padBottom;
    let newRadius = Math.min(availCircleWidth, availCircleHeight) / 2;
    const minHorizontalRadius = minCircleRatio * seriesBox.width / 2;
    const minVerticalRadius = minCircleRatio * seriesBox.height / 2;
    const minRadius = Math.min(minHorizontalRadius, minVerticalRadius);
    if (newRadius < minRadius) {
      newRadius = minRadius;
      const horizontalPadding = padLeft + padRight;
      const verticalPadding = padTop + padBottom;
      if (2 * newRadius + verticalPadding > seriesBox.height) {
        const padHeight = seriesBox.height - 2 * newRadius;
        if (Math.min(padTop, padBottom) * 2 > padHeight) {
          padTop = padHeight / 2;
          padBottom = padHeight / 2;
        } else if (padTop > padBottom) {
          padTop = padHeight - padBottom;
        } else {
          padBottom = padHeight - padTop;
        }
      }
      if (2 * newRadius + horizontalPadding > seriesBox.width) {
        const padWidth = seriesBox.width - 2 * newRadius;
        if (Math.min(padLeft, padRight) * 2 > padWidth) {
          padLeft = padWidth / 2;
          padRight = padWidth / 2;
        } else if (padLeft > padRight) {
          padLeft = padWidth - padRight;
        } else {
          padRight = padWidth - padLeft;
        }
      }
    }
    const newWidth = padLeft + 2 * newRadius + padRight;
    const newHeight = padTop + 2 * newRadius + padBottom;
    return {
      centerX: seriesBox.x + (seriesBox.width - newWidth) / 2 + padLeft + newRadius,
      centerY: seriesBox.y + (seriesBox.height - newHeight) / 2 + padTop + newRadius,
      radius: newRadius
    };
  }
};
_PolarChart.className = "PolarChart";
_PolarChart.type = "polar";
var PolarChart = _PolarChart;
var debug = Debug.create(true, "opts");
function chartType(options) {
  if (isAgCartesianChartOptions(options)) {
    return "cartesian";
  } else if (isAgPolarChartOptions(options)) {
    return "polar";
  } else if (isAgHierarchyChartOptions(options)) {
    return "hierarchy";
  }
  throw new Error(`AG Chart - unknown type of chart for options with type: ${options.type}`);
}
var _AgCharts = class _AgCharts2 {
  static licenseCheck(options) {
    var _a, _b, _c, _d;
    if (this.licenseChecked)
      return;
    this.licenseManager = (_b = (_a = enterpriseModule).licenseManager) == null ? void 0 : _b.call(_a, options);
    (_c = this.licenseManager) == null ? void 0 : _c.setLicenseKey(this.licenseKey);
    (_d = this.licenseManager) == null ? void 0 : _d.validateLicense();
    this.licenseChecked = true;
  }
  static setLicenseKey(licenseKey) {
    this.licenseKey = licenseKey;
  }
  /**
   * Returns the `AgChartInstance` for a DOM node, if there is one.
   */
  static getInstance(element2) {
    return AgChartsInternal.getInstance(element2);
  }
  /**
   * Create a new `AgChartInstance` based upon the given configuration options.
   */
  static create(options) {
    var _a, _b, _c, _d;
    this.licenseCheck(options);
    const chart = AgChartsInternal.createOrUpdate(options);
    if ((_a = this.licenseManager) == null ? void 0 : _a.isDisplayWatermark()) {
      (_d = (_c = enterpriseModule).injectWatermark) == null ? void 0 : _d.call(
        _c,
        (_b = options.document) != null ? _b : document,
        chart.chart.element,
        this.licenseManager.getWatermarkMessage()
      );
    }
    return chart;
  }
  /**
   * Update an existing `AgChartInstance`. Options provided should be complete and not
   * partial.
   *
   * __NOTE__: As each call could trigger a chart redraw, multiple calls to update options in
   * quick succession could result in undesirable flickering, so callers should batch up and/or
   * debounce changes to avoid unintended partial update renderings.
   */
  static update(chart, options) {
    if (!AgChartInstanceProxy.isInstance(chart)) {
      throw new Error(_AgCharts2.INVALID_CHART_REF_MESSAGE);
    }
    AgChartsInternal.createOrUpdate(options, chart);
  }
  /**
   * Update an existing `AgChartInstance` by applying a partial set of option changes.
   *
   * __NOTE__: As each call could trigger a chart redraw, each individual delta options update
   * should leave the chart in a valid options state. Also, multiple calls to update options in
   * quick succession could result in undesirable flickering, so callers should batch up and/or
   * debounce changes to avoid unintended partial update renderings.
   */
  static updateDelta(chart, deltaOptions) {
    if (!AgChartInstanceProxy.isInstance(chart)) {
      throw new Error(_AgCharts2.INVALID_CHART_REF_MESSAGE);
    }
    AgChartsInternal.updateUserDelta(chart, deltaOptions);
  }
  /**
   * Starts a browser-based image download for the given `AgChartInstance`.
   */
  static download(chart, options) {
    if (!(chart instanceof AgChartInstanceProxy)) {
      throw new Error(_AgCharts2.INVALID_CHART_REF_MESSAGE);
    }
    AgChartsInternal.download(chart, options);
  }
  /**
   * Returns a base64-encoded image data URL for the given `AgChartInstance`.
   */
  static getImageDataURL(chart, options) {
    if (!(chart instanceof AgChartInstanceProxy)) {
      throw new Error(_AgCharts2.INVALID_CHART_REF_MESSAGE);
    }
    return AgChartsInternal.getImageDataURL(chart, options);
  }
};
_AgCharts.INVALID_CHART_REF_MESSAGE = "AG Charts - invalid chart reference passed";
_AgCharts.licenseChecked = false;
var AgCharts = _AgCharts;
var AgChart = class _AgChart {
  static warnDeprecated(memberName) {
    const warnDeprecated = createDeprecationWarning();
    warnDeprecated(`AgChart.${memberName}`, `Use AgCharts.${memberName} instead`);
  }
  static create(options) {
    _AgChart.warnDeprecated("create");
    return AgCharts.create(options);
  }
  static update(chart, options) {
    _AgChart.warnDeprecated("update");
    return AgCharts.update(chart, options);
  }
  static updateDelta(chart, deltaOptions) {
    _AgChart.warnDeprecated("updateDelta");
    return AgCharts.updateDelta(chart, deltaOptions);
  }
  static download(chart, options) {
    _AgChart.warnDeprecated("download");
    return AgCharts.download(chart, options);
  }
  static getImageDataURL(chart, options) {
    _AgChart.warnDeprecated("getImageDataURL");
    return AgCharts.getImageDataURL(chart, options);
  }
};
var proxyInstances = /* @__PURE__ */ new WeakMap();
var _AgChartsInternal = class _AgChartsInternal2 {
  static getInstance(element2) {
    const chart = Chart.getInstance(element2);
    return chart != null ? proxyInstances.get(chart) : void 0;
  }
  static initialiseModules() {
    if (_AgChartsInternal2.initialised)
      return;
    registerInbuiltModules();
    setupModules();
    _AgChartsInternal2.initialised = true;
  }
  static createOrUpdate(userOptions, proxy) {
    var _b;
    _AgChartsInternal2.initialiseModules();
    debug(">>> AgChartV2.createOrUpdate() user options", userOptions);
    const _a = userOptions, { overrideDevicePixelRatio, document: document2, window: userWindow } = _a, chartOptions = __objRest(_a, ["overrideDevicePixelRatio", "document", "window"]);
    const specialOverrides = { overrideDevicePixelRatio, document: document2, window: userWindow };
    const processedOptions = prepareOptions(chartOptions);
    let chart = proxy == null ? void 0 : proxy.chart;
    if (chart != null) {
      proxyInstances.delete(chart);
    }
    if (chart == null || chartType(chartOptions) !== chartType(chart.processedOptions)) {
      chart = _AgChartsInternal2.createChartInstance(processedOptions, specialOverrides, chart);
    }
    if (proxy == null) {
      proxy = new AgChartInstanceProxy(chart);
    } else {
      proxy.chart = chart;
    }
    proxyInstances.set(chart, proxy);
    if (Debug.check() && typeof window !== "undefined") {
      (_b = window.agChartInstances) != null ? _b : window.agChartInstances = {};
      window.agChartInstances[chart.id] = chart;
    }
    const chartToUpdate = chart;
    chartToUpdate.queuedUserOptions.push(chartOptions);
    const dequeue = () => {
      const queuedOptionsIdx = chartToUpdate.queuedUserOptions.indexOf(chartOptions);
      chartToUpdate.queuedUserOptions.splice(0, queuedOptionsIdx);
    };
    chartToUpdate.requestFactoryUpdate(() => __async(this, null, function* () {
      if (chartToUpdate.destroyed)
        return;
      const deltaOptions = jsonDiff(chartToUpdate.processedOptions, processedOptions);
      if (deltaOptions == null) {
        dequeue();
        return;
      }
      yield _AgChartsInternal2.updateDelta(chartToUpdate, deltaOptions, chartOptions);
      dequeue();
    }));
    return proxy;
  }
  static updateUserDelta(proxy, deltaOptions) {
    var _a;
    const {
      chart,
      chart: { queuedUserOptions }
    } = proxy;
    const lastUpdateOptions = (_a = queuedUserOptions[queuedUserOptions.length - 1]) != null ? _a : chart.userOptions;
    const userOptions = jsonMerge([lastUpdateOptions, deltaOptions]);
    debug(">>> AgChartV2.updateUserDelta() user delta", deltaOptions);
    debug("AgChartV2.updateUserDelta() - base options", lastUpdateOptions);
    _AgChartsInternal2.createOrUpdate(userOptions, proxy);
  }
  /**
   * Returns the content of the current canvas as an image.
   * @param opts The download options including `width` and `height` of the image as well as `fileName` and `fileFormat`.
   */
  static download(proxy, opts) {
    const asyncDownload = () => __async(this, null, function* () {
      const maybeClone = yield _AgChartsInternal2.prepareResizedChart(proxy, opts);
      const { chart } = maybeClone;
      chart.scene.download(opts == null ? void 0 : opts.fileName, opts == null ? void 0 : opts.fileFormat);
      if (maybeClone !== proxy) {
        maybeClone.destroy();
      }
    });
    asyncDownload().catch((e) => Logger.errorOnce(e));
  }
  static getImageDataURL(proxy, opts) {
    return __async(this, null, function* () {
      const maybeClone = yield _AgChartsInternal2.prepareResizedChart(proxy, opts);
      const { chart } = maybeClone;
      const result = chart.scene.canvas.getDataURL(opts == null ? void 0 : opts.fileFormat);
      if (maybeClone !== proxy) {
        maybeClone.destroy();
      }
      return result;
    });
  }
  static prepareResizedChart(proxy, opts) {
    return __async(this, null, function* () {
      var _a;
      const { chart } = proxy;
      let { width, height } = opts != null ? opts : {};
      const currentWidth = chart.width;
      const currentHeight = chart.height;
      const unchanged = width === void 0 && height === void 0 || chart.scene.canvas.pixelRatio === 1 && currentWidth === width && currentHeight === height;
      if (unchanged) {
        return proxy;
      }
      width != null ? width : width = currentWidth;
      height != null ? height : height = currentHeight;
      const options = __spreadProps(__spreadValues({}, chart.userOptions), {
        container: document.createElement("div"),
        width,
        height,
        autoSize: false,
        overrideDevicePixelRatio: 1
      });
      if (hasRegisteredEnterpriseModules()) {
        (_a = options.animation) != null ? _a : options.animation = {};
        options.animation.enabled = false;
      }
      const clonedChart = _AgChartsInternal2.createOrUpdate(options);
      yield clonedChart.chart.waitForUpdate();
      return clonedChart;
    });
  }
  static createChartInstance(options, specialOverrides, oldChart) {
    const transferableResource = oldChart == null ? void 0 : oldChart.destroy({ keepTransferableResources: true });
    if (isAgCartesianChartOptions(options)) {
      return new CartesianChart(specialOverrides, transferableResource);
    } else if (isAgHierarchyChartOptions(options)) {
      return new HierarchyChart(specialOverrides, transferableResource);
    } else if (isAgPolarChartOptions(options)) {
      return new PolarChart(specialOverrides, transferableResource);
    }
    throw new Error(
      `AG Charts - couldn't apply configuration, check options are correctly structured and series types are specified`
    );
  }
  static updateDelta(chart, processedOptions, userOptions) {
    return __async(this, null, function* () {
      var _a;
      if (processedOptions.type == null) {
        processedOptions = __spreadProps(__spreadValues({}, processedOptions), {
          type: (_a = chart.processedOptions.type) != null ? _a : optionsType(processedOptions)
        });
      }
      if (chart.destroyed)
        return;
      debug("AgChartV2.updateDelta() - applying delta", processedOptions);
      applyChartOptions(chart, processedOptions, userOptions);
    });
  }
};
_AgChartsInternal.initialised = false;
var AgChartsInternal = _AgChartsInternal;
function applyChartOptions(chart, processedOptions, userOptions) {
  var _a, _b, _c;
  const completeOptions = jsonMerge([(_a = chart.processedOptions) != null ? _a : {}, processedOptions], noDataCloneMergeOptions);
  const modulesChanged = applyModules(chart, completeOptions);
  const skip = ["type", "data", "series", "listeners", "theme", "legend.listeners"];
  if (isAgCartesianChartOptions(processedOptions) || isAgPolarChartOptions(processedOptions)) {
    skip.push("axes");
  } else if (isAgHierarchyChartOptions(processedOptions)) {
  } else {
    throw new Error(
      `AG Charts - couldn't apply configuration, check type of options and chart: ${processedOptions["type"]}`
    );
  }
  if (processedOptions.listeners) {
    registerListeners(chart, processedOptions.listeners);
  }
  applyOptionValues(chart, chart.getModuleContext(), processedOptions, { skip });
  let forceNodeDataRefresh = false;
  let seriesRecreated = false;
  if (processedOptions.series && processedOptions.series.length > 0) {
    seriesRecreated = applySeries(chart, processedOptions);
    forceNodeDataRefresh = true;
  }
  if ("axes" in completeOptions && Array.isArray(completeOptions.axes)) {
    const axesPresent = applyAxes(chart, completeOptions, seriesRecreated);
    if (axesPresent) {
      forceNodeDataRefresh = true;
    }
  }
  const seriesOpts = processedOptions.series;
  const seriesDataUpdate = !!processedOptions.data || (seriesOpts == null ? void 0 : seriesOpts.some((s) => s.data != null));
  const legendKeys = getLegendKeys();
  const optionsHaveLegend = Object.values(legendKeys).some(
    (legendKey) => processedOptions[legendKey] != null
  );
  const otherRefreshUpdate = processedOptions.title != null && processedOptions.subtitle != null;
  forceNodeDataRefresh = forceNodeDataRefresh || seriesDataUpdate || optionsHaveLegend || otherRefreshUpdate;
  if (processedOptions.data) {
    chart.data = processedOptions.data;
  }
  if ((_b = processedOptions.legend) == null ? void 0 : _b.listeners) {
    Object.assign(chart.legend.listeners, processedOptions.legend.listeners);
  }
  if (processedOptions.listeners) {
    chart.updateAllSeriesListeners();
  }
  chart.processedOptions = completeOptions;
  chart.userOptions = jsonMerge([(_c = chart.userOptions) != null ? _c : {}, userOptions], noDataCloneMergeOptions);
  const majorChange = forceNodeDataRefresh || modulesChanged;
  const updateType = majorChange ? 1 : 2;
  debug("AgChartV2.applyChartOptions() - update type", ChartUpdateType[updateType]);
  chart.update(updateType, { forceNodeDataRefresh, newAnimationBatch: true });
}
function applyModules(chart, options) {
  const matchingChartType = ({ chartTypes }) => chart instanceof CartesianChart && chartTypes.includes("cartesian") || chart instanceof PolarChart && chartTypes.includes("polar") || chart instanceof HierarchyChart && chartTypes.includes("hierarchy");
  let modulesChanged = false;
  for (const module2 of REGISTERED_MODULES) {
    if (module2.type !== "root" && module2.type !== "legend") {
      continue;
    }
    const shouldBeEnabled = matchingChartType(module2) && options[module2.optionsKey] != null;
    const isEnabled = chart.isModuleEnabled(module2);
    if (shouldBeEnabled === isEnabled) {
      continue;
    }
    if (shouldBeEnabled) {
      chart.addModule(module2);
      chart[module2.optionsKey] = chart.modules.get(module2.optionsKey);
    } else {
      chart.removeModule(module2);
      delete chart[module2.optionsKey];
    }
    modulesChanged = true;
  }
  return modulesChanged;
}
function applySeries(chart, options) {
  const optSeries = options.series;
  if (!optSeries) {
    return false;
  }
  const keysToConsider = ["direction", "xKey", "yKey", "sizeKey", "angleKey", "stacked", "stackGroup"];
  let matchingTypes = chart.series.length === optSeries.length;
  for (let i = 0; i < chart.series.length && matchingTypes; i++) {
    matchingTypes && (matchingTypes = chart.series[i].type === optSeries[i].type);
    for (const key of keysToConsider) {
      matchingTypes && (matchingTypes = chart.series[i].properties[key] === optSeries[i][key]);
    }
  }
  if (matchingTypes) {
    chart.series.forEach((s, i) => {
      var _a, _b, _c, _d;
      const previousOpts = (_c = (_b = (_a = chart.processedOptions) == null ? void 0 : _a.series) == null ? void 0 : _b[i]) != null ? _c : {};
      const seriesDiff = jsonDiff(previousOpts, (_d = optSeries[i]) != null ? _d : {});
      if (!seriesDiff) {
        return;
      }
      debug(`AgChartV2.applySeries() - applying series diff idx ${i}`, seriesDiff);
      applySeriesValues(s, seriesDiff);
      s.markNodeDataDirty();
    });
    return false;
  }
  debug(`AgChartV2.applySeries() - creating new series instances`);
  chart.series = createSeries(chart, optSeries);
  return true;
}
function applyAxes(chart, options, forceRecreate) {
  const optAxes = options.axes;
  if (!optAxes) {
    return false;
  }
  const matchingTypes = !forceRecreate && chart.axes.length === optAxes.length && chart.axes.every((a, i) => a.type === optAxes[i].type);
  if (matchingTypes) {
    const oldOpts = chart.processedOptions;
    const moduleContext = chart.getModuleContext();
    if (isAgCartesianChartOptions(oldOpts)) {
      chart.axes.forEach((a, i) => {
        var _a, _b;
        const previousOpts = (_b = (_a = oldOpts.axes) == null ? void 0 : _a[i]) != null ? _b : {};
        const axisDiff = jsonDiff(previousOpts, optAxes[i]);
        debug(`AgChartV2.applyAxes() - applying axis diff idx ${i}`, axisDiff);
        const path = `axes[${i}]`;
        const skip = ["axes[].type"];
        applyOptionValues(a, moduleContext, axisDiff, { path, skip });
      });
      return true;
    }
  }
  chart.axes = createAxis(chart, optAxes);
  return true;
}
function createSeries(chart, options) {
  var _a;
  const series = [];
  const moduleContext = chart.getModuleContext();
  for (const seriesOptions of options != null ? options : []) {
    const type = (_a = seriesOptions.type) != null ? _a : "unknown";
    if (isEnterpriseSeriesType(type) && !isEnterpriseSeriesTypeLoaded(type)) {
      continue;
    }
    const seriesInstance = getSeries(type, moduleContext);
    applySeriesOptionModules(seriesInstance, seriesOptions);
    applySeriesValues(seriesInstance, seriesOptions);
    series.push(seriesInstance);
  }
  return series;
}
function applySeriesOptionModules(series, options) {
  const seriesOptionModules = REGISTERED_MODULES.filter((m) => m.type === "series-option");
  const moduleContext = series.createModuleContext();
  const moduleMap = series.getModuleMap();
  for (const module2 of seriesOptionModules) {
    const supportedSeriesTypes = module2.seriesTypes;
    if (module2.optionsKey in options && supportedSeriesTypes.includes(series.type)) {
      moduleMap.addModule(module2, (module3) => new module3.instanceConstructor(moduleContext));
      series[module2.optionsKey] = moduleMap.getModule(module2);
    }
  }
}
function createAxis(chart, options) {
  const guesser = new AxisPositionGuesser();
  const moduleContext = chart.getModuleContext();
  const skip = ["axes[].type"];
  let index = 0;
  for (const axisOptions of options != null ? options : []) {
    const axis = getAxis(axisOptions.type, moduleContext);
    const path = `axes[${index++}]`;
    applyAxisModules(axis, axisOptions);
    applyOptionValues(axis, moduleContext, axisOptions, { path, skip });
    guesser.push(axis, axisOptions);
  }
  return guesser.guessInvalidPositions();
}
function applyAxisModules(axis, options) {
  let modulesChanged = false;
  const rootModules = REGISTERED_MODULES.filter((m) => m.type === "axis-option");
  const moduleContext = axis.createModuleContext();
  for (const module2 of rootModules) {
    const shouldBeEnabled = options[module2.optionsKey] != null;
    const moduleMap = axis.getModuleMap();
    const isEnabled = moduleMap.isModuleEnabled(module2);
    if (shouldBeEnabled === isEnabled)
      continue;
    modulesChanged = true;
    if (shouldBeEnabled) {
      moduleMap.addModule(module2, (module3) => new module3.instanceConstructor(moduleContext));
      axis[module2.optionsKey] = moduleMap.getModule(module2);
    } else {
      moduleMap.removeModule(module2);
      delete axis[module2.optionsKey];
    }
  }
  return modulesChanged;
}
function registerListeners(source, listeners) {
  source.clearEventListeners();
  const entries = Object.entries(listeners != null ? listeners : {});
  for (const [property, listener] of entries) {
    if (typeof listener !== "function")
      continue;
    source.addEventListener(property, listener);
  }
}
function applyOptionValues(target, moduleContext, options, { skip, path } = {}) {
  const applyOpts = __spreadValues(__spreadProps(__spreadValues({}, getJsonApplyOptions(moduleContext)), {
    skip
  }), path ? { path } : {});
  return jsonApply(target, options, applyOpts);
}
function applySeriesValues(target, options) {
  const moduleMap = target.getModuleMap();
  const _a = options, { type, data, errorBar, listeners, seriesGrouping } = _a, seriesOptions = __objRest(_a, ["type", "data", "errorBar", "listeners", "seriesGrouping"]);
  target.properties.set(seriesOptions);
  if ("data" in options) {
    target.data = options.data;
  }
  if ("errorBar" in options && moduleMap.isModuleEnabled("errorBar")) {
    moduleMap.getModule("errorBar").properties.set(options.errorBar);
  }
  if ((options == null ? void 0 : options.listeners) != null) {
    registerListeners(target, options.listeners);
  }
  if ("seriesGrouping" in options) {
    target.seriesGrouping = seriesGrouping ? Object.freeze(__spreadValues(__spreadValues({}, target.seriesGrouping), seriesGrouping)) : void 0;
  }
}
var VERSION = "9.0.2";
var integrated_charts_theme_exports = {};
__export(integrated_charts_theme_exports, {
  BOTTOM: () => BOTTOM,
  CARTESIAN_AXIS_POSITIONS: () => CARTESIAN_AXIS_POSITIONS,
  CARTESIAN_AXIS_TYPES: () => CARTESIAN_AXIS_TYPES,
  CIRCLE: () => CIRCLE,
  ChartTheme: () => ChartTheme,
  DEFAULT_AXIS_GRID_COLOUR: () => DEFAULT_AXIS_GRID_COLOUR,
  DEFAULT_AXIS_LINE_COLOUR: () => DEFAULT_AXIS_LINE_COLOUR,
  DEFAULT_BACKGROUND_COLOUR: () => DEFAULT_BACKGROUND_COLOUR,
  DEFAULT_CROSS_LINES_COLOUR: () => DEFAULT_CROSS_LINES_COLOUR,
  DEFAULT_DIVERGING_SERIES_COLOUR_RANGE: () => DEFAULT_DIVERGING_SERIES_COLOUR_RANGE,
  DEFAULT_FONT_FAMILY: () => DEFAULT_FONT_FAMILY,
  DEFAULT_HIERARCHY_FILLS: () => DEFAULT_HIERARCHY_FILLS,
  DEFAULT_HIERARCHY_STROKES: () => DEFAULT_HIERARCHY_STROKES,
  DEFAULT_INSIDE_SERIES_LABEL_COLOUR: () => DEFAULT_INSIDE_SERIES_LABEL_COLOUR,
  DEFAULT_INVERTED_LABEL_COLOUR: () => DEFAULT_INVERTED_LABEL_COLOUR,
  DEFAULT_LABEL_COLOUR: () => DEFAULT_LABEL_COLOUR,
  DEFAULT_MUTED_LABEL_COLOUR: () => DEFAULT_MUTED_LABEL_COLOUR,
  DEFAULT_POLAR_SERIES_STROKE: () => DEFAULT_POLAR_SERIES_STROKE,
  DEFAULT_SHADOW_COLOUR: () => DEFAULT_SHADOW_COLOUR,
  DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE: () => DEFAULT_WATERFALL_SERIES_CONNECTOR_LINE_STROKE,
  DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS: () => DEFAULT_WATERFALL_SERIES_NEGATIVE_COLOURS,
  DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS: () => DEFAULT_WATERFALL_SERIES_POSITIVE_COLOURS,
  DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS: () => DEFAULT_WATERFALL_SERIES_TOTAL_COLOURS,
  EXTENDS_AXES_DEFAULTS: () => EXTENDS_AXES_DEFAULTS,
  EXTENDS_AXES_GRID_LINE_DEFAULTS: () => EXTENDS_AXES_GRID_LINE_DEFAULTS,
  EXTENDS_AXES_LABEL_DEFAULTS: () => EXTENDS_AXES_LABEL_DEFAULTS,
  EXTENDS_AXES_LINE_DEFAULTS: () => EXTENDS_AXES_LINE_DEFAULTS,
  EXTENDS_AXES_TICK_DEFAULTS: () => EXTENDS_AXES_TICK_DEFAULTS,
  EXTENDS_CARTESIAN_MARKER_DEFAULTS: () => EXTENDS_CARTESIAN_MARKER_DEFAULTS,
  EXTENDS_CHART_DEFAULTS: () => EXTENDS_CHART_DEFAULTS,
  EXTENDS_LEGEND_DEFAULTS: () => EXTENDS_LEGEND_DEFAULTS,
  EXTENDS_LEGEND_ITEM_DEFAULTS: () => EXTENDS_LEGEND_ITEM_DEFAULTS,
  EXTENDS_LEGEND_ITEM_MARKER_DEFAULTS: () => EXTENDS_LEGEND_ITEM_MARKER_DEFAULTS,
  EXTENDS_SERIES_DEFAULTS: () => EXTENDS_SERIES_DEFAULTS,
  FONT_SIZE: () => FONT_SIZE,
  FONT_WEIGHT: () => FONT_WEIGHT2,
  OVERRIDE_SERIES_LABEL_DEFAULTS: () => OVERRIDE_SERIES_LABEL_DEFAULTS,
  POLAR_AXIS_TYPES: () => POLAR_AXIS_TYPES,
  getChartTheme: () => getChartTheme,
  themes: () => themes2
});
var themes2 = Object.entries(themes).reduce(
  (obj, [name, factory]) => {
    obj[name] = factory();
    return obj;
  },
  {}
);
var sparklines_scale_exports = {};
__export(sparklines_scale_exports, {
  BandScale: () => BandScale,
  ColorScale: () => ColorScale,
  ContinuousScale: () => ContinuousScale,
  Invalidating: () => Invalidating,
  LinearScale: () => LinearScale,
  TimeScale: () => TimeScale
});
if (typeof module.exports == "object" && typeof exports == "object") {
  var __cp = (to, from, except, desc) => {
    if ((from && typeof from === "object") || typeof from === "function") {
      for (let key of Object.getOwnPropertyNames(from)) {
        if (!Object.prototype.hasOwnProperty.call(to, key) && key !== except)
        Object.defineProperty(to, key, {
          get: () => from[key],
          enumerable: !(desc = Object.getOwnPropertyDescriptor(from, key)) || desc.enumerable,
        });
      }
    }
    return to;
  };
  module.exports = __cp(module.exports, exports);
}
return module.exports;
}))
